girparser: Guess virtual method wrapper variant when possible
[vala-lang.git] / vala / valalockstatement.vala
blobe0d4216f91a64d259cd39a0117ebced437eb5c5d
1 /* valalockstatement.vala
3 * Copyright (C) 2009 Jiří Zárevúcky
4 * Copyright (C) 2006-2010 Jürg Billeter
5 * Copyright (C) 2006-2007 Raffaele Sandrini
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Authors:
22 * Raffaele Sandrini <raffaele@sandrini.ch>
23 * Jiří Zárevúcky <zarevucky.jiri@gmail.com>
26 using GLib;
28 /**
29 * Represents a lock statement e.g. {{{ lock (a); }}} or {{{ lock (a) { f(a); } }}}.
31 * If the statement is empty, the mutex remains locked until a corresponding UnlockStatement
32 * occurs. Otherwise it's translated into a try/finally statement which unlocks the mutex
33 * after the block is finished.
35 public class Vala.LockStatement : CodeNode, Statement {
36 /**
37 * Expression representing the resource to be locked.
39 public Expression resource { get; set; }
41 /**
42 * The statement during its execution the resource is locked.
44 public Block? body { get; set; }
46 public LockStatement (Expression resource, Block? body, SourceReference? source_reference = null) {
47 this.body = body;
48 this.source_reference = source_reference;
49 this.resource = resource;
52 public override void accept (CodeVisitor visitor) {
53 resource.accept (visitor);
54 if (body != null) {
55 body.accept (visitor);
57 visitor.visit_lock_statement (this);
60 public override bool check (CodeContext context) {
61 if (body != null) {
62 // if the statement isn't empty, it is converted into a try statement
64 var fin_body = new Block (source_reference);
65 fin_body.add_statement (new UnlockStatement (resource, source_reference));
67 var block = new Block (source_reference);
68 block.add_statement (new LockStatement (resource, null, source_reference));
69 block.add_statement (new TryStatement (body, fin_body, source_reference));
71 var parent_block = (Block) parent_node;
72 parent_block.replace_statement (this, block);
74 return block.check (context);
77 if (checked) {
78 return !error;
81 checked = true;
83 resource.check (context);
85 /* resource must be a member access and denote a Lockable */
86 if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) {
87 error = true;
88 resource.error = true;
89 Report.error (resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
90 return false;
93 /* parent symbol must be the current class */
94 if (resource.symbol_reference.parent_symbol != context.analyzer.current_class) {
95 error = true;
96 resource.error = true;
97 Report.error (resource.source_reference, "Only members of the current class are lockable");
100 ((Lockable) resource.symbol_reference).set_lock_used (true);
102 return !error;
105 public override void emit (CodeGenerator codegen) {
106 resource.emit (codegen);
107 codegen.visit_lock_statement (this);