add support for pointer member access
authorJuerg Billeter <j@bitron.ch>
Thu, 20 Dec 2007 22:07:12 +0000 (22:07 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 20 Dec 2007 22:07:12 +0000 (22:07 +0000)
2007-12-20  Juerg Billeter  <j@bitron.ch>

* vala/parser.y, vala/scanner.l, vala/valacodecontext.vala,
  vala/valadatatype.vala, vala/valamemberaccess.vala,
  vala/valapointertype.vala, vala/valasemanticanalyzer.vala,
  gobject/valadbusbindingprovider.vala: add support for pointer member
  access

svn path=/trunk/; revision=782

ChangeLog
gobject/valadbusbindingprovider.vala
vala/parser.y
vala/scanner.l
vala/valacodecontext.vala
vala/valadatatype.vala
vala/valamemberaccess.vala
vala/valapointertype.vala
vala/valasemanticanalyzer.vala

index d37c3e6..cf9e965 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-12-20  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y, vala/scanner.l, vala/valacodecontext.vala,
+         vala/valadatatype.vala, vala/valamemberaccess.vala,
+         vala/valapointertype.vala, vala/valasemanticanalyzer.vala,
+         gobject/valadbusbindingprovider.vala: add support for pointer member
+         access
+
 2007-12-18  Jürg Billeter  <j@bitron.ch>
 
        * vapi/sqlite3.vapi: some enhancements to the SQLite bindings
index 7e8b402..2ff2c0a 100644 (file)
@@ -60,7 +60,7 @@ public class Vala.DBusBindingProvider : Object, BindingProvider {
                        Iterator<DataType> type_args_it = type_args.iterator ();
                        type_args_it.next ();
                        var ret_type = type_args_it.get ().copy ();
-                       if (!is_dbus_interface (ret_type.data_type)) {
+                       if (!is_dbus_interface (ret_type)) {
                                return null;
                        }
                        var m = _context.create_method ("get_object", ret_type, ma.source_reference);
@@ -72,7 +72,7 @@ public class Vala.DBusBindingProvider : Object, BindingProvider {
                        m.add_parameter (_context.create_formal_parameter ("path", string_type_ref));
                        symbols.add (m);
                        return m;
-               } else if (ma.inner != null && ma.inner.static_type != null && is_dbus_interface (ma.inner.static_type.data_type)) {
+               } else if (ma.inner != null && ma.inner.static_type != null && is_dbus_interface (ma.inner.static_type)) {
                        if (ma.parent_node is InvocationExpression) {
                                var expr = (InvocationExpression) ma.parent_node;
                                var ret_type = new DataType ();
@@ -104,11 +104,11 @@ public class Vala.DBusBindingProvider : Object, BindingProvider {
                return null;
        }
 
-       private bool is_dbus_interface (Typesymbol! t) {
-               if (!(t is Interface)) {
+       private bool is_dbus_interface (DataType! t) {
+               if (!(t.data_type is Interface)) {
                        return false;
                }
-               return (t.get_attribute ("DBusInterface") != null);
+               return (t.data_type.get_attribute ("DBusInterface") != null);
        }
 }
 
index 191c37e..a33cb26 100644 (file)
@@ -145,6 +145,8 @@ static gboolean check_is_struct (ValaSymbol *symbol, ValaSourceReference *src);
 %token OP_AND "&&"
 %token TILDE "~"
 
+%token OP_PTR "->"
+
 %token ASSIGN "="
 %token PLUS "+"
 %token MINUS "-"
@@ -238,6 +240,7 @@ static gboolean check_is_struct (ValaSymbol *symbol, ValaSourceReference *src);
 %type <expression> simple_name
 %type <expression> parenthesized_expression
 %type <expression> member_access
+%type <expression> pointer_member_access
 %type <expression> invocation_expression
 %type <expression> element_access
 %type <list> expression_list
@@ -715,6 +718,7 @@ primary_no_array_creation_expression
        | simple_name
        | parenthesized_expression
        | member_access
+       | pointer_member_access
        | invocation_expression
        | element_access
        | this_access
@@ -780,6 +784,26 @@ member_access
          }
        ;
 
+pointer_member_access
+       : primary_expression OP_PTR identifier opt_type_argument_list
+         {
+               ValaSourceReference *src = src(@3);
+               $$ = VALA_EXPRESSION (vala_code_context_create_member_access_pointer (context, $1, $3, src));
+               g_object_unref ($1);
+               g_free ($3);
+               g_object_unref (src);
+
+               if ($4 != NULL) {
+                       GList *l;
+                       for (l = $4; l != NULL; l = l->next) {
+                               vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($4);
+               }
+         }
+       ;
+
 invocation_expression
        : primary_expression open_parens opt_argument_list CLOSE_PARENS
          {
index 80bafc1..cb9ac8e 100644 (file)
@@ -120,6 +120,8 @@ literal                             ({integer_literal}|{real_literal}|{character_literal}|{string_literal
 "^"            { uploc; return CARRET; }
 "~"            { uploc; return TILDE; }
 
+"->"           { uploc; return OP_PTR; }
+
 "="            { uploc; return ASSIGN; }
 "+"            { uploc; return PLUS; }
 "-"            { uploc; return MINUS; }
index 75b2281..0feb6af 100644 (file)
@@ -681,6 +681,12 @@ public class Vala.CodeContext : Object {
                return node;
        }
 
+       public MemberAccess! create_member_access_pointer (Expression inner, string! member_name, SourceReference source_reference = null) {
+               var node = new MemberAccess.pointer (inner, member_name, source_reference);
+               node.code_binding = codegen.create_member_access_binding (node);
+               return node;
+       }
+
        public InvocationExpression! create_invocation_expression (Expression! call, SourceReference source_reference = null) {
                var node = new InvocationExpression (call, source_reference);
                node.code_binding = codegen.create_invocation_expression_binding (node);
index 1260a77..58e9771 100644 (file)
@@ -456,4 +456,8 @@ public class Vala.DataType : CodeNode {
                }
                return symbols;
        }
+
+       public virtual Symbol get_pointer_member (string member_name) {
+               return null;
+       }
 }
index 5a2d468..59fcb30 100644 (file)
@@ -48,6 +48,11 @@ public class Vala.MemberAccess : Expression {
        public string! member_name { get; set; }
 
        /**
+        * Pointer member access.
+        */
+       public bool pointer_member_access { get; set; }
+
+       /**
         * Represents access to an instance member without an actual instance,
         * e.g. `MyClass.an_instance_method`.
         */
@@ -74,7 +79,11 @@ public class Vala.MemberAccess : Expression {
 
        public MemberAccess.simple (construct string! member_name, construct SourceReference source_reference = null) {
        }
-       
+
+       public MemberAccess.pointer (construct Expression inner, construct string! member_name, construct SourceReference source_reference = null) {
+               pointer_member_access = true;
+       }
+
        /**
         * Appends the specified type as generic type argument.
         *
index 9851a2a..c54bd71 100644 (file)
@@ -62,4 +62,14 @@ public class Vala.PointerType : DataType {
 
                return false;
        }
+
+       public override Symbol get_pointer_member (string member_name) {
+               Symbol base_symbol = base_type.data_type;
+
+               if (base_symbol == null) {
+                       return null;
+               }
+
+               return SemanticAnalyzer.symbol_lookup_inherited (base_symbol, member_name);
+       }
 }
index 1362ff9..43ce031 100644 (file)
@@ -1333,8 +1333,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
 
                        if (expr.symbol_reference == null && expr.inner.static_type != null) {
-                               base_symbol = expr.inner.static_type.data_type;
-                               expr.symbol_reference = symbol_lookup_inherited (base_symbol, expr.member_name);
+                               if (expr.pointer_member_access) {
+                                       expr.symbol_reference = expr.inner.static_type.get_pointer_member (expr.member_name);
+                               } else {
+                                       base_symbol = expr.inner.static_type.data_type;
+                                       expr.symbol_reference = symbol_lookup_inherited (base_symbol, expr.member_name);
+                               }
                                if (expr.symbol_reference != null) {
                                        // inner expression is variable, field, or parameter
                                        // access to instance members of the corresponding type possible
@@ -1602,7 +1606,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                return null;
                        }
                        foreach (DataType base_type in base_types) {
-                               if (SemanticAnalyzer.symbol_lookup_inherited (base_type.data_type, generic_member.name) != null) {
+                               if (symbol_lookup_inherited (base_type.data_type, generic_member.name) != null) {
                                        // construct a new type reference for the base type with correctly linked type arguments
                                        ReferenceType instance_base_type;
                                        if (base_type.data_type is Class) {