2
* Copyright (C) 2008 Abderrahim Kitouni
3
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
/* Finds the innermost block containing the given location */
21
public class ValaLocator: Vala.CodeVisitor {
26
public Location (int line, int column) {
31
public bool inside (Vala.SourceReference src) {
32
var begin = Location (src.begin.line, src.begin.column);
33
var end = Location (src.end.line, src.end.column);
35
return begin.before (this) && this.before(end);
38
public bool before (Location other) {
39
if (line > other.line)
41
else if (line == other.line && column > other.column)
48
Vala.Symbol innermost;
49
Location innermost_begin;
50
Location innermost_end;
52
public Vala.Symbol? locate (Vala.SourceFile file, int line, int column) {
53
location = Location (line, column);
55
file.accept_children(this);
59
bool update_location (Vala.Symbol s) {
60
if (!location.inside (s.source_reference))
63
var begin = Location (s.source_reference.begin.line, s.source_reference.begin.column);
64
var end = Location (s.source_reference.end.line, s.source_reference.end.column);
66
if (innermost == null || (innermost_begin.before(begin) && end.before(innermost_end))) {
68
innermost_begin = begin;
76
public override void visit_block (Vala.Block b) {
77
if (update_location (b))
78
b.accept_children(this);
81
public override void visit_namespace (Vala.Namespace ns) {
83
ns.accept_children(this);
85
public override void visit_class (Vala.Class cl) {
86
/* the location of a class contains only its declaration, not its content */
87
if (update_location (cl))
89
cl.accept_children(this);
91
public override void visit_struct (Vala.Struct st) {
92
if (update_location (st))
94
st.accept_children(this);
96
public override void visit_interface (Vala.Interface iface) {
97
if (update_location (iface))
99
iface.accept_children(this);
102
public override void visit_method (Vala.Method m) {
103
if (update_location (m))
105
m.accept_children(this);
107
public override void visit_creation_method (Vala.CreationMethod m) {
108
if (update_location (m))
110
m.accept_children(this);
112
public override void visit_property (Vala.Property prop) {
113
prop.accept_children(this);
115
public override void visit_property_accessor (Vala.PropertyAccessor acc) {
116
acc.accept_children(this);
118
public override void visit_constructor (Vala.Constructor c) {
119
c.accept_children(this);
121
public override void visit_destructor (Vala.Destructor d) {
122
d.accept_children(this);
124
public override void visit_if_statement (Vala.IfStatement stmt) {
125
stmt.accept_children(this);
127
public override void visit_switch_statement (Vala.SwitchStatement stmt) {
128
stmt.accept_children(this);
130
public override void visit_switch_section (Vala.SwitchSection section) {
131
visit_block (section);
133
public override void visit_while_statement (Vala.WhileStatement stmt) {
134
stmt.accept_children(this);
136
public override void visit_do_statement (Vala.DoStatement stmt) {
137
stmt.accept_children(this);
139
public override void visit_for_statement (Vala.ForStatement stmt) {
140
stmt.accept_children(this);
142
public override void visit_foreach_statement (Vala.ForeachStatement stmt) {
143
stmt.accept_children(this);
145
public override void visit_try_statement (Vala.TryStatement stmt) {
146
stmt.accept_children(this);
148
public override void visit_catch_clause (Vala.CatchClause clause) {
149
clause.accept_children(this);
151
public override void visit_lock_statement (Vala.LockStatement stmt) {
152
stmt.accept_children(this);
154
public override void visit_expression_statement (Vala.ExpressionStatement stmt) {
155
stmt.accept_children (this);
157
public override void visit_declaration_statement (Vala.DeclarationStatement stmt) {
158
stmt.accept_children (this);
160
public override void visit_local_variable (Vala.LocalVariable variable) {
161
variable.accept_children (this);
163
public override void visit_end_full_expression (Vala.Expression expr) {
164
if (expr is Vala.LambdaExpression)
165
visit_method ((expr as Vala.LambdaExpression).method);
166
if (expr is Vala.MethodCall) {
167
foreach (Vala.Expression e in (expr as Vala.MethodCall).get_argument_list()) {
168
visit_expression (e);
172
public override void visit_expression (Vala.Expression expr) {
173
if (expr is Vala.LambdaExpression)
174
visit_method ((expr as Vala.LambdaExpression).method);
175
if (expr is Vala.MethodCall) {
176
foreach (Vala.Expression e in (expr as Vala.MethodCall).get_argument_list())
177
visit_expression (e);