Commit 2cce5057 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

add support for pointer member access

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
parent 954a7952
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
......
......@@ -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);
}
}
......@@ -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
{
......
......@@ -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; }
......
......@@ -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);
......
......@@ -456,4 +456,8 @@ public class Vala.DataType : CodeNode {
}
return symbols;
}
public virtual Symbol get_pointer_member (string member_name) {
return null;
}
}
......@@ -47,6 +47,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.
*
......
......@@ -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);
}
}
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment