Line data Source code
1 : /* valaunlockstatement.vala
2 : *
3 : * Copyright (C) 2009-2010 Jürg Billeter
4 : * Copyright (C) 2009 Jiří Zárevúcky
5 : *
6 : * This library is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public
8 : * License as published by the Free Software Foundation; either
9 : * version 2.1 of the License, or (at your option) any later version.
10 :
11 : * This library is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 :
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this library; if not, write to the Free Software
18 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 : *
20 : * Author:
21 : * Jiří Zárevúcky <zarevucky.jiri@gmail.com>
22 : */
23 :
24 : /**
25 : * Represents an unlock statement.
26 : *
27 : * {{{ unlock (foo); }}}
28 : */
29 47 : public class Vala.UnlockStatement : CodeNode, Statement {
30 : /**
31 : * Expression representing the resource to be unlocked.
32 : */
33 : public Expression resource {
34 228 : get { return _resource; }
35 29 : private set {
36 29 : _resource = value;
37 29 : _resource.parent_node = this;
38 : }
39 : }
40 :
41 29 : private Expression _resource;
42 :
43 87 : public UnlockStatement (Expression resource, SourceReference? source_reference = null) {
44 29 : this.source_reference = source_reference;
45 29 : this.resource = resource;
46 : }
47 :
48 29 : public override void accept (CodeVisitor visitor) {
49 29 : resource.accept (visitor);
50 29 : visitor.visit_unlock_statement (this);
51 : }
52 :
53 0 : public override void replace_expression (Expression old_node, Expression new_node) {
54 0 : if (resource == old_node) {
55 0 : resource = new_node;
56 : }
57 : }
58 :
59 29 : public override bool check (CodeContext context) {
60 29 : if (checked) {
61 0 : return !error;
62 : }
63 :
64 29 : checked = true;
65 :
66 29 : resource.check (context);
67 :
68 : /* resource must be a member access and denote a Lockable */
69 29 : if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) {
70 1 : error = true;
71 1 : resource.error = true;
72 1 : Report.error (resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
73 1 : return false;
74 : }
75 :
76 : /* parent symbol must be the current class */
77 28 : if (resource.symbol_reference.parent_symbol != context.analyzer.current_class) {
78 1 : error = true;
79 1 : resource.error = true;
80 1 : Report.error (resource.source_reference, "Only members of the current class are lockable");
81 1 : return false;
82 : }
83 :
84 : /* parent class must not be compact */
85 27 : if (context.analyzer.current_class.is_compact) {
86 1 : error = true;
87 1 : resource.error = true;
88 1 : Report.error (resource.source_reference, "Only members of the non-compact classes are lockable");
89 1 : return false;
90 : }
91 :
92 26 : ((Lockable) resource.symbol_reference).lock_used = true;
93 :
94 26 : return !error;
95 : }
96 :
97 26 : public override void emit (CodeGenerator codegen) {
98 26 : resource.emit (codegen);
99 26 : codegen.visit_unlock_statement (this);
100 : }
101 : }
|