Generate correct code for calling class methods outside of static or class
authorJared Moore <jaredm@svn.gnome.org>
Sun, 10 Aug 2008 02:20:26 +0000 (02:20 +0000)
committerJared William Moore <jaredm@src.gnome.org>
Sun, 10 Aug 2008 02:20:26 +0000 (02:20 +0000)
2008-08-10  Jared Moore  <jaredm@svn.gnome.org>

* gobject/valaccodeinvocationexpressionbinding.vala:

Generate correct code for calling class methods outside of static or
class constructors, fixes bug 539592.

* tests/classes-methods.vala:
* tests/classes-methods.exp:

Added test cases for calling class methods.

svn path=/trunk/; revision=1738

ChangeLog
gobject/valaccodecompiler.vala
gobject/valaccodeinvocationexpressionbinding.vala
tests/classes-methods.exp
tests/classes-methods.vala

index 151edc2..0195129 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-08-10  Jared Moore  <jaredm@svn.gnome.org>
+
+       * gobject/valaccodeinvocationexpressionbinding.vala:
+
+       Generate correct code for calling class methods outside of static or
+       class constructors, fixes bug 539592.
+
+       * tests/classes-methods.vala:
+       * tests/classes-methods.exp:
+
+       Added test cases for calling class methods.
+
 2008-08-06  Thijs Vermeir  <thijsvermeir@gmail.com>
 
        * vapi/packages/gstreamer-0.10/gstreamer-0.10.metadata:
index 9be754c..70f9664 100644 (file)
@@ -113,7 +113,7 @@ public class Vala.CCodeCompiler : Object {
 
                // add libraries after source files to fix linking
                // with --as-needed and on Windows
-               cmdline += " " + pkgflags;
+               cmdline += " " + pkgflags.strip ();
                foreach (string cc_option in cc_options) {
                        cmdline += " " + Shell.quote (cc_option);
                }
index 57646e8..a133834 100644 (file)
@@ -98,8 +98,27 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                } 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"));
+                       
+                       CCodeExpression klass;
+                       var ma = expr.call as MemberAccess;
+                       if (ma.inner == null) {
+                               if (codegen.in_static_or_class_ctor) {
+                                       // Accessing the method from a static or class constructor
+                                       klass = new CCodeIdentifier ("klass");
+                               } else {
+                                       // Accessing the method from within an instance method
+                                       var k = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_GET_CLASS"));
+                                       k.add_argument (new CCodeIdentifier ("self"));
+                                       klass = k;
+                               }
+                       } else {
+                               // Accessing the method of an instance
+                               var k = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_GET_CLASS"));
+                               k.add_argument ((CCodeExpression) ma.inner.ccodenode);
+                               klass = k;
+                       }
 
+                       cast.add_argument (klass);
                        carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), cast);
                }
 
index 6e621cb..b32fe50 100644 (file)
@@ -2,3 +2,7 @@ Inheritance Test: 1 2 3
 Static Inheritance Test: 1 2 3
 Virtual Method Test: 1 2 3
 Interface Inheritance Test: 1 2 3
+Access class method in class constructor: OK
+Access class method in static constructor: OK
+Access class method by member access: OK
+Access class method in instance method: OK
index e3854d0..33696ca 100644 (file)
@@ -81,6 +81,8 @@ class Maman.SubBar : Bar {
                test_ref_weak (ref str2);
                assert (str == "world");
 
+               ClassTest.run_test ();
+
                return 0;
        }
 }
@@ -183,3 +185,33 @@ void test_ref_weak (ref weak string bar) {
        bar = "world";
 }
 
+class Maman.ClassTest {
+       public class void class_method () {
+               stdout.printf(" OK\n");
+       }
+
+       public void instance_method () {
+               stdout.printf ("Access class method in instance method:");
+               class_method ();
+       }
+
+       class construct {
+               stdout.printf ("Access class method in class constructor:");
+               class_method ();
+       }
+
+       static construct {
+               stdout.printf ("Access class method in static constructor:");
+               class_method ();
+       }
+
+       public static void run_test () {
+               var c = new ClassTest ();
+
+               stdout.printf ("Access class method by member access:");
+               c.class_method ();
+
+               c.instance_method ();
+       }
+}
+