girparser: Better support for arrays in return type.
[vala-lang.git] / vala / valapostfixexpression.vala
blob065381ae096c83178d98a00f9ad58a11d0169d55
1 /* valapostfixexpression.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using GLib;
25 /**
26 * Represents a postfix increment or decrement expression.
28 public class Vala.PostfixExpression : Expression {
29 /**
30 * The operand, must be a variable or a property.
32 public Expression inner { get; set; }
34 /**
35 * Specifies whether value should be incremented or decremented.
37 public bool increment { get; set; }
39 /**
40 * Creates a new postfix expression.
42 * @param inner operand expression
43 * @param inc true for increment, false for decrement
44 * @param source reference to source code
45 * @return newly created postfix expression
47 public PostfixExpression (Expression _inner, bool inc, SourceReference source) {
48 inner = _inner;
49 increment = inc;
50 source_reference = source;
53 public override void accept (CodeVisitor visitor) {
54 visitor.visit_postfix_expression (this);
56 visitor.visit_expression (this);
59 public override void accept_children (CodeVisitor visitor) {
60 inner.accept (visitor);
63 public override bool is_pure () {
64 return false;
67 public override bool check (CodeContext context) {
68 if (checked) {
69 return !error;
72 checked = true;
74 if (!inner.check (context)) {
75 error = true;
76 return false;
79 if (!(inner.value_type is IntegerType) && !(inner.value_type is FloatingType) && !(inner.value_type is PointerType)) {
80 error = true;
81 Report.error (source_reference, "unsupported lvalue in postfix expression");
82 return false;
85 if (inner is MemberAccess) {
86 var ma = (MemberAccess) inner;
88 if (ma.prototype_access) {
89 error = true;
90 Report.error (source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
91 return false;
94 if (ma.error || ma.symbol_reference == null) {
95 error = true;
96 /* if no symbol found, skip this check */
97 return false;
99 } else if (inner is ElementAccess) {
100 var ea = (ElementAccess) inner;
101 if (!(ea.container.value_type is ArrayType)) {
102 error = true;
103 Report.error (source_reference, "unsupported lvalue in postfix expression");
104 return false;
106 } else {
107 error = true;
108 Report.error (source_reference, "unsupported lvalue in postfix expression");
109 return false;
112 if (inner is MemberAccess) {
113 var ma = (MemberAccess) inner;
115 if (ma.symbol_reference is Property) {
116 var prop = (Property) ma.symbol_reference;
118 if (prop.set_accessor == null || !prop.set_accessor.writable) {
119 ma.error = true;
120 Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
121 return false;
126 value_type = inner.value_type;
128 return !error;
131 public override void emit (CodeGenerator codegen) {
132 inner.emit (codegen);
134 codegen.visit_postfix_expression (this);
136 codegen.visit_expression (this);