See the attachment.
Without this patch the default signal handler is barely useful, since
'this' is not added to the hidden method's scope. The original test-case
didn't cover this issue. My bad.
----Test case ---
public class Test {
public void print_this() {
message("%p", this);
}
public virtual signal void test() {
this.print_this();
print_this();
}
public static void main() {
Test t = new Test();
t.test();
}
}
------Cut ends----
Yu
>From af5a0cf9b0e5b5ec4c581aaf4dc0b590eafd6139 Mon Sep 17 00:00:00 2001
From: Yu Feng <[email protected]>
Date: Mon, 31 Aug 2009 20:21:45 -0400
Subject: [PATCH] Fix `this` access in def-signal-handlers(bz593734)
A new method, `add_hidden_method` is added into Vala.Class.
This method set up the method's scope and this_parameter,
but adds the method into methods collection.
These methods are hidden and anonymous from the class's point of
view, which is indeed useful for the default signal handlers.
There may also be other useful cases for these hidden methods,
which I couldn't dig out from my head with an empty stomach.
---
vala/valaclass.vala | 30 ++++++++++++++++++++++++++++++
vala/valasignal.vala | 7 ++++++-
2 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 63b93e1..9f885c8 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -360,6 +360,36 @@ public class Vala.Class : ObjectTypeSymbol {
}
/**
+ * Adds the specified method as a hidden member to this class,
+ * primarily used for default signal handlers.
+ *
+ * The hidden methods are not part of the `methods` collection.
+ *
+ * There may also be other use cases, eg, convert array.resize() to
+ * this type of method?
+ *
+ * @param m a method
+ */
+ public void add_hidden_method (Method m) {
+ if (m.binding == MemberBinding.INSTANCE) {
+ if (m.this_parameter != null) {
+ m.scope.remove (m.this_parameter.name);
+ }
+ m.this_parameter = new FormalParameter ("this", get_this_type ());
+ m.scope.add (m.this_parameter.name, m.this_parameter);
+ }
+ if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
+ if (m.result_var != null) {
+ m.scope.remove (m.result_var.name);
+ }
+ m.result_var = new LocalVariable (m.return_type.copy (), "result");
+ m.result_var.is_result = true;
+ }
+
+ scope.add (null, m);
+ }
+
+ /**
* Returns a copy of the list of methods.
*
* @return list of methods
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index 79ede73..ea4dc95 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -247,6 +247,8 @@ public class Vala.Signal : Member, Lockable {
if (is_virtual) {
default_handler = new Method (name, return_type, source_reference);
+
+ default_handler.owner = owner;
default_handler.access = access;
default_handler.external = external;
default_handler.is_virtual = true;
@@ -254,11 +256,14 @@ public class Vala.Signal : Member, Lockable {
default_handler.signal_reference = this;
default_handler.body = body;
+
foreach (FormalParameter param in parameters) {
default_handler.add_parameter (param);
}
- parent_symbol.scope.add (null, default_handler);
+ var cl = parent_symbol as Class;
+
+ cl.add_hidden_method(default_handler);
default_handler.check (analyzer);
}
return !error;
--
1.6.2.5
_______________________________________________
Vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list