Sync NEWS from 0.40
[vala-gnome.git] / vala / valapostfixexpression.vala
blobeed39a39a0d0e60c0948ca083cf2e74aaea9ca95
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 {
33 get { return _inner; }
34 set {
35 _inner = value;
36 _inner.parent_node = this;
40 /**
41 * Specifies whether value should be incremented or decremented.
43 public bool increment { get; set; }
45 private Expression _inner;
47 /**
48 * Creates a new postfix expression.
50 * @param _inner operand expression
51 * @param inc true for increment, false for decrement
52 * @param source reference to source code
53 * @return newly created postfix expression
55 public PostfixExpression (Expression _inner, bool inc, SourceReference source) {
56 inner = _inner;
57 increment = inc;
58 source_reference = source;
61 public override void accept (CodeVisitor visitor) {
62 visitor.visit_postfix_expression (this);
64 visitor.visit_expression (this);
67 public override void accept_children (CodeVisitor visitor) {
68 inner.accept (visitor);
71 public override bool is_pure () {
72 return false;
75 public override bool is_accessible (Symbol sym) {
76 return inner.is_accessible (sym);
79 public override void get_defined_variables (Collection<Variable> collection) {
80 inner.get_defined_variables (collection);
81 var local = inner.symbol_reference as LocalVariable;
82 var param = inner.symbol_reference as Parameter;
83 if (local != null) {
84 collection.add (local);
85 } else if (param != null && param.direction == ParameterDirection.OUT) {
86 collection.add (param);
90 public override void get_used_variables (Collection<Variable> collection) {
91 inner.get_used_variables (collection);
94 public override bool check (CodeContext context) {
95 if (checked) {
96 return !error;
99 checked = true;
101 inner.lvalue = true;
102 if (!inner.check (context)) {
103 error = true;
104 return false;
107 if (!(inner.value_type is IntegerType) && !(inner.value_type is FloatingType) && !(inner.value_type is PointerType)) {
108 error = true;
109 Report.error (source_reference, "unsupported lvalue in postfix expression");
110 return false;
113 if (inner is MemberAccess) {
114 var ma = (MemberAccess) inner;
116 if (ma.prototype_access) {
117 error = true;
118 Report.error (source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
119 return false;
122 if (ma.error || ma.symbol_reference == null) {
123 error = true;
124 /* if no symbol found, skip this check */
125 return false;
127 } else if (inner is ElementAccess) {
128 var ea = (ElementAccess) inner;
129 if (!(ea.container.value_type is ArrayType)) {
130 error = true;
131 Report.error (source_reference, "unsupported lvalue in postfix expression");
132 return false;
134 } else {
135 error = true;
136 Report.error (source_reference, "unsupported lvalue in postfix expression");
137 return false;
140 if (inner is MemberAccess) {
141 var ma = (MemberAccess) inner;
143 if (ma.symbol_reference is Property) {
144 var prop = (Property) ma.symbol_reference;
146 if (prop.set_accessor == null || !prop.set_accessor.writable) {
147 ma.error = true;
148 Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
149 return false;
154 value_type = inner.value_type;
156 return !error;
159 public override void emit (CodeGenerator codegen) {
160 inner.emit (codegen);
162 codegen.visit_postfix_expression (this);
164 codegen.visit_expression (this);