From: Juerg Billeter Date: Thu, 20 Dec 2007 22:07:12 +0000 (+0000) Subject: add support for pointer member access X-Git-Tag: VALA_0_1_6~85 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2cce50575883ff545f2dbd5bc60f5e7584bc6eb0;p=platform%2Fupstream%2Fvala.git add support for pointer member access 2007-12-20 Juerg Billeter * 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 --- diff --git a/ChangeLog b/ChangeLog index d37c3e6..cf9e965 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-12-20 Jürg Billeter + + * 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 * vapi/sqlite3.vapi: some enhancements to the SQLite bindings diff --git a/gobject/valadbusbindingprovider.vala b/gobject/valadbusbindingprovider.vala index 7e8b402..2ff2c0a 100644 --- a/gobject/valadbusbindingprovider.vala +++ b/gobject/valadbusbindingprovider.vala @@ -60,7 +60,7 @@ public class Vala.DBusBindingProvider : Object, BindingProvider { Iterator 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); } } diff --git a/vala/parser.y b/vala/parser.y index 191c37e..a33cb26 100644 --- a/vala/parser.y +++ b/vala/parser.y @@ -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 simple_name %type parenthesized_expression %type member_access +%type pointer_member_access %type invocation_expression %type element_access %type 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 { diff --git a/vala/scanner.l b/vala/scanner.l index 80bafc1..cb9ac8e 100644 --- a/vala/scanner.l +++ b/vala/scanner.l @@ -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; } diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index 75b2281..0feb6af 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -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); diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index 1260a77..58e9771 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -456,4 +456,8 @@ public class Vala.DataType : CodeNode { } return symbols; } + + public virtual Symbol get_pointer_member (string member_name) { + return null; + } } diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index 5a2d468..59fcb30 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -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. * diff --git a/vala/valapointertype.vala b/vala/valapointertype.vala index 9851a2a..c54bd71 100644 --- a/vala/valapointertype.vala +++ b/vala/valapointertype.vala @@ -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); + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 1362ff9..43ce031 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -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) {