]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Extend signal details to support string expressions
authorLuca Bruno <lethalman88@gmail.com>
Fri, 20 Aug 2010 15:13:44 +0000 (17:13 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 21 Aug 2010 08:47:10 +0000 (10:47 +0200)
Fixes bug 566909.

codegen/valadbusservermodule.vala
codegen/valagdbusservermodule.vala
codegen/valagsignalmodule.vala
tests/Makefile.am
tests/objects/bug566909.vala [new file with mode: 0644]

index 5a2ea3ecb20084ade59e62077074c7e7c6124765..3986d97c7d26ef04e69f792909e56df13911a12d 100644 (file)
@@ -1488,7 +1488,7 @@ public class Vala.DBusServerModule : DBusClientModule {
 
                        var connect = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_connect"));
                        connect.add_argument (new CCodeIdentifier ("object"));
-                       connect.add_argument (sig.get_canonical_cconstant (null));
+                       connect.add_argument (sig.get_canonical_cconstant ());
                        connect.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_dbus_signal_wrapper (sig, sym, dbus_iface_name)), "GCallback"));
                        connect.add_argument (new CCodeIdentifier ("connection"));
                        block.add_statement (new CCodeExpressionStatement (connect));
index c924d93a096dd1e59e17d9c20784ad5d8cd0922b..8d22467fb5c4067cf44bbaa2ccddc4e2cb4ade4d 100644 (file)
@@ -597,7 +597,7 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 
                        var connect = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_connect"));
                        connect.add_argument (new CCodeIdentifier ("object"));
-                       connect.add_argument (sig.get_canonical_cconstant (null));
+                       connect.add_argument (sig.get_canonical_cconstant ());
                        connect.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_dbus_signal_wrapper (sig, sym, dbus_iface_name)), "GCallback"));
                        connect.add_argument (new CCodeIdentifier ("data"));
                        block.add_statement (new CCodeExpressionStatement (connect));
index e36f5f248827dfcc3e10ceadd710a37cee09c67b..2605f2b74237a1e9fe7c1baef20c7fc386734c02 100644 (file)
@@ -147,7 +147,37 @@ public class Vala.GSignalModule : GObjectModule {
                
                return signature;
        }
-       
+
+       private CCodeExpression? get_signal_name_cexpression (Signal sig, Expression? detail_expr, CodeNode node) {
+               if (detail_expr == null) {
+                       return sig.get_canonical_cconstant ();
+               }
+
+               if (detail_expr.value_type is NullType || !detail_expr.value_type.compatible (string_type)) {
+                       node.error = true;
+                       Report.error (detail_expr.source_reference, "only string details are supported");
+                       return null;
+               }
+
+               if (detail_expr is StringLiteral) {
+                       return sig.get_canonical_cconstant (((StringLiteral) detail_expr).eval ());
+               }
+
+               var detail_decl = get_temp_variable (detail_expr.value_type, true, node);
+               temp_vars.insert (0, detail_decl);
+               temp_ref_vars.insert (0, detail_decl);
+
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
+               ccall.add_argument (sig.get_canonical_cconstant (""));
+               ccall.add_argument ((CCodeExpression) detail_expr.ccodenode);
+               ccall.add_argument (new CCodeConstant ("NULL"));
+
+               var ccomma = new CCodeCommaExpression ();
+               ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (detail_decl.name), ccall));
+               ccomma.append_expression (get_variable_cexpression (detail_decl.name));
+               return ccomma;
+       }
+
        public override void visit_signal (Signal sig) {
                // parent_symbol may be null for dynamic signals
 
@@ -457,13 +487,14 @@ public class Vala.GSignalModule : GObjectModule {
                        var sig = (Signal) expr.symbol_reference;
                        var ma = (MemberAccess) expr.container;
 
-                       var detail_expr = expr.get_indices ().get (0) as StringLiteral;
-                       string signal_detail = detail_expr.eval ();
+                       var detail_expr = expr.get_indices ().get (0);
+                       var signal_name_cexpr = get_signal_name_cexpression (sig, detail_expr, expr);
                        
                        var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
                        ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
-                       ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
-                       
+                       if (signal_name_cexpr != null) {
+                               ccall.add_argument (signal_name_cexpr);
+                       }
                        expr.ccodenode = ccall;
                } else {
                        base.visit_element_access (expr);
@@ -601,22 +632,21 @@ public class Vala.GSignalModule : GObjectModule {
 
                var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
 
-               string signal_detail = null;
+               CCodeExpression signal_name_cexpr = null;
 
                // first argument: instance of sender
                MemberAccess ma;
                if (signal_access is ElementAccess) {
                        var ea = (ElementAccess) signal_access;
                        ma = (MemberAccess) ea.container;
-                       var detail_expr = ea.get_indices ().get (0) as StringLiteral;
-                       if (detail_expr == null) {
-                               expr.error = true;
-                               Report.error (detail_expr.source_reference, "internal error: only literal string details supported");
+                       var detail_expr = ea.get_indices ().get (0);
+                       signal_name_cexpr = get_signal_name_cexpression (sig, detail_expr, expr);
+                       if (signal_name_cexpr == null) {
                                return null;
                        }
-                       signal_detail = detail_expr.eval ();
                } else {
                        ma = (MemberAccess) signal_access;
+                       signal_name_cexpr = get_signal_name_cexpression (sig, null, expr);
                }
                if (ma.inner != null) {
                        ccall.add_argument ((CCodeExpression) get_ccodenode (ma.inner));
@@ -635,12 +665,12 @@ public class Vala.GSignalModule : GObjectModule {
                        // g_signal_connect_object or g_signal_connect
 
                        // second argument: signal name
-                       ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
+                       ccall.add_argument (signal_name_cexpr);
                } else {
                        // g_signal_handlers_disconnect_matched
 
                        // second argument: mask
-                       if (signal_detail == null) {
+                       if (!(signal_access is ElementAccess)) {
                                ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
                        } else {
                                ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
@@ -651,12 +681,12 @@ public class Vala.GSignalModule : GObjectModule {
                        var temp_decl = get_temp_variable (uint_type);
                        temp_vars.add (temp_decl);
                        var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
-                       parse_call.add_argument (sig.get_canonical_cconstant (signal_detail));
+                       parse_call.add_argument (signal_name_cexpr);
                        var decl_type = (TypeSymbol) sig.parent_symbol;
                        parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
                        parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_decl.name)));
                        LocalVariable? detail_temp_decl = null;
-                       if (signal_detail == null) {
+                       if (!(signal_access is ElementAccess)) {
                                parse_call.add_argument (new CCodeConstant ("NULL"));
                                parse_call.add_argument (new CCodeConstant ("FALSE"));
                        } else {
index e09841a0ce0d920584758a131e042a0d449572c4..24304071b30384c46392e699e210592318e170ab 100644 (file)
@@ -63,6 +63,7 @@ TESTS = \
        objects/test-026.vala \
        objects/test-029.vala \
        objects/test-034.vala \
+       objects/bug566909.vala \
        objects/bug593260.vala \
        objects/bug596621.vala \
        objects/bug597155.vala \
diff --git a/tests/objects/bug566909.vala b/tests/objects/bug566909.vala
new file mode 100644 (file)
index 0000000..0af250b
--- /dev/null
@@ -0,0 +1,18 @@
+class Maman.Foo : Object {
+       [Signal (detailed = true)]
+       public signal void bar ();
+}
+
+void main () {
+       bool detailed1 = false;
+       bool detailed2 = false;
+       string detail1 = "detail1";
+       string detail2 = "detail2";
+
+       var foo = new Maman.Foo ();
+       foo.bar[detail1].connect (() => { detailed1 = true; });
+       foo.bar[detail2].connect (() => { detailed2 = true; });
+       foo.bar[detail1] ();
+       foo.bar[detail2] ();
+       assert (detailed1 && detailed2);
+}