summaryrefslogtreecommitdiff
path: root/vala
diff options
context:
space:
mode:
Diffstat (limited to 'vala')
-rw-r--r--vala/parser.y24
-rw-r--r--vala/scanner.l2
-rw-r--r--vala/valacodecontext.vala6
-rw-r--r--vala/valadatatype.vala4
-rw-r--r--vala/valamemberaccess.vala11
-rw-r--r--vala/valapointertype.vala10
-rw-r--r--vala/valasemanticanalyzer.vala10
7 files changed, 63 insertions, 4 deletions
diff --git a/vala/parser.y b/vala/parser.y
index 191c37e7d..a33cb2677 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 <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
{
diff --git a/vala/scanner.l b/vala/scanner.l
index 80bafc1e4..cb9ac8eb0 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 75b228137..0feb6aff9 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 1260a7728..58e97710e 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 5a2d46855..59fcb300d 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 9851a2a8d..c54bd71d6 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 1362ff999..43ce031d5 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) {