]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add initial support for static methods in generic types
authorJürg Billeter <j@bitron.ch>
Wed, 3 Jun 2009 07:21:36 +0000 (09:21 +0200)
committerJürg Billeter <j@bitron.ch>
Wed, 3 Jun 2009 07:25:38 +0000 (09:25 +0200)
Fixes bug 471512.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodcallmodule.vala
codegen/valaccodemethodmodule.vala
vala/valasemanticanalyzer.vala

index bd639cb117e872a4a288690d70d0360984f68a40..c7d1bf074ec327013a2b081e0d1521bc5a369db8 100644 (file)
@@ -1716,10 +1716,19 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                return local;
        }
 
+       bool is_in_generic_type (DataType type) {
+               if (type.type_parameter.parent_symbol is TypeSymbol
+                   && (current_method == null || current_method.binding == MemberBinding.INSTANCE)) {
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
        private CCodeExpression get_type_id_expression (DataType type) {
                if (type is GenericType) {
                        string var_name = "%s_type".printf (type.type_parameter.name.down ());
-                       if (type.type_parameter.parent_symbol is TypeSymbol) {
+                       if (is_in_generic_type (type)) {
                                return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), var_name);
                        } else {
                                return new CCodeIdentifier (var_name);
@@ -1769,7 +1778,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                        return new CCodeIdentifier (dup_function);
                } else if (type.type_parameter != null && current_type_symbol is Class) {
                        string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
-                       if (type.type_parameter.parent_symbol is TypeSymbol) {
+                       if (is_in_generic_type (type)) {
                                return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
                        } else {
                                return new CCodeIdentifier (func_name);
@@ -1899,7 +1908,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                        return new CCodeIdentifier (unref_function);
                } else if (type.type_parameter != null && current_type_symbol is Class) {
                        string func_name = "%s_destroy_func".printf (type.type_parameter.name.down ());
-                       if (type.type_parameter.parent_symbol is TypeSymbol) {
+                       if (is_in_generic_type (type)) {
                                return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
                        } else {
                                return new CCodeIdentifier (func_name);
index adb4434541f66f53838451ccb51ba81f1bb68f8b..f62ff3acafa4a9b6c5e542d3d4c54ec3da56d9fa 100644 (file)
@@ -102,8 +102,18 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                        break;
                                }
                        }
-               } else if (m != null && m.get_type_parameters ().size > 0) {
-                       add_generic_type_arguments (ccall, ma.get_type_arguments (), expr);
+               } else if (m != null) {
+                       if (m.binding != MemberBinding.INSTANCE && m.parent_symbol is ObjectTypeSymbol) {
+                               // support static methods in generic types
+                               var type_symbol = (ObjectTypeSymbol) m.parent_symbol;
+                               if (type_symbol.get_type_parameters ().size > 0 && ma.inner is MemberAccess) {
+                                       var type_ma = (MemberAccess) ma.inner;
+                                       add_generic_type_arguments (ccall, type_ma.get_type_arguments (), expr);
+                               }
+                       }
+                       if (m.get_type_parameters ().size > 0) {
+                               add_generic_type_arguments (ccall, ma.get_type_arguments (), expr);
+                       }
                }
 
                // the complete call expression, might include casts, comma expressions, and/or assignments
index 0bd87c89c1a69fa00f9910eabb82d24a8ab2a03d..e1e3de1af189561b4d6e0f127798bea8768cb17e 100644 (file)
@@ -742,6 +742,21 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                        }
                } else {
                        int type_param_index = 0;
+                       if (m.binding != MemberBinding.INSTANCE && m.parent_symbol is ObjectTypeSymbol) {
+                               // support static methods in generic types
+                               var type_symbol = (ObjectTypeSymbol) m.parent_symbol;
+                               foreach (var type_param in type_symbol.get_type_parameters ()) {
+                                       cparam_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType"));
+                                       cparam_map.set (get_param_pos (0.1 * type_param_index + 0.02), new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc"));
+                                       cparam_map.set (get_param_pos (0.1 * type_param_index + 0.03), new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify"));
+                                       if (carg_map != null) {
+                                               carg_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
+                                               carg_map.set (get_param_pos (0.1 * type_param_index + 0.02), new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ())));
+                                               carg_map.set (get_param_pos (0.1 * type_param_index + 0.03), new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ())));
+                                       }
+                                       type_param_index++;
+                               }
+                       }
                        foreach (var type_param in m.get_type_parameters ()) {
                                cparam_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType"));
                                cparam_map.set (get_param_pos (0.1 * type_param_index + 0.02), new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc"));
index 1bef37711d8f21ee691356bfe904965bb5e9036d..cf3c1e66f399b7894146838841afd4669d6c6fa5 100644 (file)
@@ -552,34 +552,40 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public static DataType? get_actual_type (DataType? derived_instance_type, MemberAccess? method_access, GenericType generic_type, CodeNode node_reference) {
+               DataType actual_type = null;
                if (generic_type.type_parameter.parent_symbol is TypeSymbol) {
-                       if (derived_instance_type == null) {
-                               return generic_type;
-                       }
+                       if (derived_instance_type != null) {
+                               // trace type arguments back to the datatype where the method has been declared
+                               var instance_type = get_instance_base_type_for_member (derived_instance_type, (TypeSymbol) generic_type.type_parameter.parent_symbol, node_reference);
 
-                       // trace type arguments back to the datatype where the method has been declared
-                       var instance_type = get_instance_base_type_for_member (derived_instance_type, (TypeSymbol) generic_type.type_parameter.parent_symbol, node_reference);
+                               assert (instance_type != null);
 
-                       assert (instance_type != null);
+                               int param_index = instance_type.data_type.get_type_parameter_index (generic_type.type_parameter.name);
+                               if (param_index == -1) {
+                                       Report.error (node_reference.source_reference, "internal error: unknown type parameter %s".printf (generic_type.type_parameter.name));
+                                       node_reference.error = true;
+                                       return null;
+                               }
 
-                       int param_index = instance_type.data_type.get_type_parameter_index (generic_type.type_parameter.name);
-                       if (param_index == -1) {
-                               Report.error (node_reference.source_reference, "internal error: unknown type parameter %s".printf (generic_type.type_parameter.name));
-                               node_reference.error = true;
-                               return null;
-                       }
+                               if (param_index < instance_type.get_type_arguments ().size) {
+                                       actual_type = (DataType) instance_type.get_type_arguments ().get (param_index);
+                               }
+                       } else if (method_access != null && method_access.inner is MemberAccess) {
+                               // static method in generic type
+                               var type_symbol = (ObjectTypeSymbol) generic_type.type_parameter.parent_symbol;
 
-                       DataType actual_type = null;
-                       if (param_index < instance_type.get_type_arguments ().size) {
-                               actual_type = (DataType) instance_type.get_type_arguments ().get (param_index);
-                       }
-                       if (actual_type == null) {
-                               // no actual type available
-                               return generic_type;
+                               int param_index = type_symbol.get_type_parameter_index (generic_type.type_parameter.name);
+                               if (param_index == -1) {
+                                       Report.error (node_reference.source_reference, "internal error: unknown type parameter %s".printf (generic_type.type_parameter.name));
+                                       node_reference.error = true;
+                                       return null;
+                               }
+
+                               var type_ma = (MemberAccess) method_access.inner;
+                               if (param_index < type_ma.get_type_arguments ().size) {
+                                       actual_type = (DataType) type_ma.get_type_arguments ().get (param_index);
+                               }
                        }
-                       actual_type = actual_type.copy ();
-                       actual_type.value_owned = actual_type.value_owned && generic_type.value_owned;
-                       return actual_type;
                } else {
                        // generic method
                        var m = (Method) generic_type.type_parameter.parent_symbol;
@@ -595,18 +601,18 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                return null;
                        }
 
-                       DataType actual_type = null;
                        if (param_index < method_access.get_type_arguments ().size) {
                                actual_type = (DataType) method_access.get_type_arguments ().get (param_index);
                        }
-                       if (actual_type == null) {
-                               // no actual type available
-                               return generic_type;
-                       }
-                       actual_type = actual_type.copy ();
-                       actual_type.value_owned = actual_type.value_owned && generic_type.value_owned;
-                       return actual_type;
                }
+
+               if (actual_type == null) {
+                       // no actual type available
+                       return generic_type;
+               }
+               actual_type = actual_type.copy ();
+               actual_type.value_owned = actual_type.value_owned && generic_type.value_owned;
+               return actual_type;
        }
 
        public bool is_in_instance_method () {