diff options
author | Luca Bruno <lucabru@src.gnome.org> | 2013-09-21 11:34:06 +0200 |
---|---|---|
committer | Luca Bruno <lucabru@src.gnome.org> | 2013-09-21 11:34:06 +0200 |
commit | ed8f32bd6696291a1bc49597b70c30335ec2917d (patch) | |
tree | 0b3a5be189e23ce21cfb08173a2e2fbf0f9e7364 | |
parent | fe764132afa6e8b39fc7b0791f7ba257066e7945 (diff) | |
download | vala-ed8f32bd6696291a1bc49597b70c30335ec2917d.tar.gz |
Support chain up to constructv functions.
-rw-r--r-- | codegen/valaccodebasemodule.vala | 12 | ||||
-rw-r--r-- | codegen/valaccodemethodcallmodule.vala | 10 | ||||
-rw-r--r-- | codegen/valaccodemethodmodule.vala | 18 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/objects/chainup.vala | 39 | ||||
-rw-r--r-- | vala/valaclass.vala | 4 | ||||
-rw-r--r-- | vala/valamethodcall.vala | 19 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 2 |
8 files changed, 84 insertions, 21 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index e42c5785e..5cdd816cd 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -6205,6 +6205,18 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { return get_ccode_attribute(sym).real_name; } + public static string get_ccode_constructv_name (CreationMethod m) { + const string infix = "constructv"; + + var parent = m.parent_symbol as Class; + + if (m.name == ".new") { + return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix); + } else { + return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name); + } + } + public static string get_ccode_vfunc_name (Method m) { return get_ccode_attribute(m).vfunc_name; } diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index 0bd462a13..728dccdd4 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -48,6 +48,8 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { // Enum.VALUE.to_string() var en = (Enum) ma.inner.value_type.data_type; ccall.call = new CCodeIdentifier (generate_enum_tostring_function (en)); + } else if (expr.is_constructv_chainup) { + ccall.call = new CCodeIdentifier (get_ccode_constructv_name ((CreationMethod) m)); } } else if (itype is SignalType) { var sig_type = (SignalType) itype; @@ -61,7 +63,11 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { var cl = (Class) ((ObjectType) itype).type_symbol; m = cl.default_construction_method; generate_method_declaration (m, cfile); - ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m))); + var real_name = get_ccode_real_name (m); + if (expr.is_constructv_chainup) { + real_name = get_ccode_constructv_name ((CreationMethod) m); + } + ccall = new CCodeFunctionCall (new CCodeIdentifier (real_name)); } else if (itype is StructValueType) { // constructor var st = (Struct) ((StructValueType) itype).type_symbol; @@ -598,7 +604,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { * except when using printf-style arguments */ if (m == null) { in_arg_map.set (get_param_pos (-1, true), new CCodeConstant ("NULL")); - } else if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "") { + } else if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "" && !expr.is_constructv_chainup) { in_arg_map.set (get_param_pos (-1, true), new CCodeConstant (get_ccode_sentinel (m))); } } diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index f0cddaec1..c7c7818f7 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -204,7 +204,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { if (m.is_variadic ()) { // _constructv function - function = new CCodeFunction (get_constructv_name ((CreationMethod) m)); + function = new CCodeFunction (get_ccode_constructv_name ((CreationMethod) m)); cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal); generate_cparameters (m, decl_space, cparam_map, function); @@ -214,18 +214,6 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { } } - private string get_constructv_name (CreationMethod m) { - const string infix = "constructv"; - - var parent = m.parent_symbol as Class; - - if (m.name == ".new") { - return "%s%s".printf (CCodeBaseModule.get_ccode_lower_case_prefix (parent), infix); - } else { - return "%s%s_%s".printf (CCodeBaseModule.get_ccode_lower_case_prefix (parent), infix, m.name); - } - } - void register_plugin_types (Symbol sym, Set<Symbol> registered_types) { var ns = sym as Namespace; var cl = sym as Class; @@ -289,7 +277,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { public override void visit_method (Method m) { string real_name = get_ccode_real_name (m); if (m is CreationMethod && m.is_variadic ()) { - real_name = get_constructv_name ((CreationMethod) m); + real_name = get_ccode_constructv_name ((CreationMethod) m); } push_context (new EmitContext (m)); @@ -1182,7 +1170,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { push_function (vfunc); - string constructor = (m.is_variadic ()) ? get_constructv_name (m) : get_ccode_real_name (m); + string constructor = (m.is_variadic ()) ? get_ccode_constructv_name (m) : get_ccode_real_name (m); var vcall = new CCodeFunctionCall (new CCodeIdentifier (constructor)); if (self_as_first_parameter) { diff --git a/tests/Makefile.am b/tests/Makefile.am index b84ee0411..b84d433eb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -100,6 +100,7 @@ TESTS = \ delegates/bug638415.vala \ delegates/bug639751.vala \ delegates/bug703804.vala \ + objects/chainup.vala \ objects/classes.vala \ objects/fields.vala \ objects/interfaces.vala \ diff --git a/tests/objects/chainup.vala b/tests/objects/chainup.vala new file mode 100644 index 000000000..fdca08d67 --- /dev/null +++ b/tests/objects/chainup.vala @@ -0,0 +1,39 @@ +class FooBase { + public int bar; + + public FooBase (int _, ...) { + va_list v = va_list (); + bar = v.arg (); + } + + public FooBase.baz (int _, ...) { + va_list v = va_list (); + this (_, v); + } +} + +class Foo : FooBase { + public Foo (int _, ...) { + va_list v = va_list (); + base (_, v); + } + + public Foo.baz (int _, ...) { + va_list v = va_list (); + base.baz (_, v); + } + + public Foo.qux (int _, ...) { + va_list v = va_list (); + this.baz (_, v); + } +} + +void main () { + var foo = new Foo (0, 10); + assert (foo.bar == 10); + foo = new Foo.baz (0, 20); + assert (foo.bar == 20); + foo = new Foo.qux (0, 30); + assert (foo.bar == 30); +} diff --git a/vala/valaclass.vala b/vala/valaclass.vala index 5110a7aa6..ba23a508f 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -151,7 +151,7 @@ public class Vala.Class : ObjectTypeSymbol { /** * Specifies the default construction method. */ - public Method default_construction_method { get; set; } + public CreationMethod default_construction_method { get; set; } /** * Specifies the instance constructor. @@ -303,7 +303,7 @@ public class Vala.Class : ObjectTypeSymbol { } if (m is CreationMethod) { if (m.name == null) { - default_construction_method = m; + default_construction_method = (CreationMethod) m; m.name = ".new"; } diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index 5b0ba8a1d..89d2ba5cc 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -41,6 +41,11 @@ public class Vala.MethodCall : Expression { public bool is_assert { get; private set; } + /** + * Whether this chain up uses the constructv function with va_list. + */ + public bool is_constructv_chainup { get; private set; } + public Expression _call; private List<Expression> argument_list = new ArrayList<Expression> (); @@ -213,6 +218,8 @@ public class Vala.MethodCall : Expression { var mtype = call.value_type; + CreationMethod base_cm = null; + if (mtype is ObjectType || call.symbol_reference == context.analyzer.object_type) { // constructor chain-up var cm = context.analyzer.find_current_method () as CreationMethod; @@ -230,7 +237,7 @@ public class Vala.MethodCall : Expression { if (mtype is ObjectType) { var otype = (ObjectType) mtype; var cl = (Class) otype.type_symbol; - var base_cm = cl.default_construction_method; + base_cm = cl.default_construction_method; if (base_cm == null) { error = true; Report.error (source_reference, "chain up to `%s' not supported".printf (cl.get_full_name ())); @@ -301,7 +308,7 @@ public class Vala.MethodCall : Expression { } cm.chain_up = true; - var base_cm = (CreationMethod) call.symbol_reference; + base_cm = (CreationMethod) call.symbol_reference; if (!base_cm.has_construct_function) { error = true; Report.error (source_reference, "chain up to `%s' not supported".printf (base_cm.get_full_name ())); @@ -720,6 +727,14 @@ public class Vala.MethodCall : Expression { return false; } + /* Check for constructv chain up */ + if (base_cm != null && base_cm.is_variadic () && args.size == base_cm.get_parameters ().size) { + var this_last_arg = args[args.size-1]; + if (this_last_arg.value_type is StructValueType && this_last_arg.value_type.data_type == context.analyzer.va_list_type.data_type) { + is_constructv_chainup = true; + } + } + if (may_throw) { if (parent_node is LocalVariable || parent_node is ExpressionStatement) { // simple statements, no side effects after method call diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 90923ac2c..8244896d0 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -150,6 +150,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { public DataType unichar_type; public DataType double_type; public DataType type_type; + public DataType va_list_type; public Class object_type; public StructValueType gvalue_type; public ObjectType gvariant_type; @@ -196,6 +197,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t")); ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t")); double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double")); + va_list_type = new StructValueType ((Struct) root_symbol.scope.lookup ("va_list")); var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar"); if (unichar_struct != null) { |