Merge lp:~monkey-libre/valide/update-afrodite into lp:valide
- update-afrodite
- Merge into trunk
Proposed by
Monkey
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 595 | ||||
Proposed branch: | lp:~monkey-libre/valide/update-afrodite | ||||
Merge into: | lp:valide | ||||
Diff against target: |
2247 lines (+774/-610) 13 files modified
plugins/completion/afrodite-provider/afrodite-provider.vala (+27/-36) plugins/completion/afrodite-provider/afrodite/Makefile.am (+1/-1) plugins/completion/afrodite-provider/afrodite/afroditetest.vala (+122/-115) plugins/completion/afrodite-provider/afrodite/ast.vala (+9/-38) plugins/completion/afrodite-provider/afrodite/astdumper.vala (+1/-1) plugins/completion/afrodite-provider/afrodite/astmerger.vala (+299/-156) plugins/completion/afrodite-provider/afrodite/completionengine.vala (+202/-199) plugins/completion/afrodite-provider/afrodite/parser.vala (+10/-11) plugins/completion/afrodite-provider/afrodite/parseresult.vala (+5/-0) plugins/completion/afrodite-provider/afrodite/sourcefile.vala (+2/-25) plugins/completion/afrodite-provider/afrodite/sourcereference.vala (+6/-6) plugins/completion/afrodite-provider/afrodite/symbol.vala (+27/-14) plugins/completion/afrodite-provider/afrodite/symbolresolver.vala (+63/-8) |
||||
To merge this branch: | bzr merge lp:~monkey-libre/valide/update-afrodite | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Val(a)IDE Team | Pending | ||
Review via email:
|
Commit message
Description of the change
Update Afrodite from vtg-0.11.1
Changes in the api:
Removed the try_acquire_ast / release_ast
Works very fast and without any problem. More info attached in the bug.
Thanks in advance.
To post a comment you must log in.
Revision history for this message

Monkey (monkey-libre) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugins/completion/afrodite-provider/afrodite-provider.vala' |
2 | --- plugins/completion/afrodite-provider/afrodite-provider.vala 2011-02-20 14:12:17 +0000 |
3 | +++ plugins/completion/afrodite-provider/afrodite-provider.vala 2011-03-10 19:26:24 +0000 |
4 | @@ -737,40 +737,35 @@ |
5 | first_part = word; // "this"; //HACK: this won't work for static methods |
6 | } |
7 | |
8 | - Afrodite.Ast ast; |
9 | + Afrodite.Ast ast = completion.ast; |
10 | Afrodite.Symbol? symbol = null; |
11 | - |
12 | - if (this.completion.try_acquire_ast (out ast, retry_count)) |
13 | - { |
14 | - Afrodite.QueryResult? result = null; |
15 | - Afrodite.QueryOptions options = this.get_options_for_line (text, is_assignment, is_creation); |
16 | - |
17 | + Afrodite.QueryResult? result = null; |
18 | + Afrodite.QueryOptions options = this.get_options_for_line (text, is_assignment, is_creation); |
19 | + |
20 | + if (word == symbol_name) |
21 | + { |
22 | + result = this.get_symbol_for_name (options, ast, first_part, null, line, col); |
23 | + } |
24 | + else |
25 | + { |
26 | + result = this.get_symbol_type_for_name (options, ast, first_part, null, line, col); |
27 | + } |
28 | + |
29 | + if (result != null && !result.is_empty) |
30 | + { |
31 | + var first = result.children.get (0); |
32 | if (word == symbol_name) |
33 | { |
34 | - result = this.get_symbol_for_name (options, ast, first_part, null, line, col); |
35 | + symbol = first.symbol; |
36 | } |
37 | else |
38 | { |
39 | - result = this.get_symbol_type_for_name (options, ast, first_part, null, line, col); |
40 | - } |
41 | - |
42 | - if (result != null && !result.is_empty) |
43 | - { |
44 | - var first = result.children.get (0); |
45 | - if (word == symbol_name) |
46 | - { |
47 | - symbol = first.symbol; |
48 | - } |
49 | - else |
50 | - { |
51 | - symbol = this.get_symbol_for_name_in_children (symbol_name, first.symbol); |
52 | - if (symbol == null) |
53 | - { |
54 | - symbol =this.get_symbol_for_name_in_base_types (symbol_name, first.symbol); |
55 | - } |
56 | - } |
57 | - } |
58 | - this.completion.release_ast (ast); |
59 | + symbol = this.get_symbol_for_name_in_children (symbol_name, first.symbol); |
60 | + if (symbol == null) |
61 | + { |
62 | + symbol =this.get_symbol_for_name_in_base_types (symbol_name, first.symbol); |
63 | + } |
64 | + } |
65 | } |
66 | return symbol; |
67 | } |
68 | @@ -857,10 +852,9 @@ |
69 | |
70 | Vtg.ParserUtils.parse_line (text, out word, out is_assignment, out is_creation, out is_declaration); |
71 | |
72 | - Afrodite.Ast ast = null; |
73 | + Afrodite.Ast ast = completion.ast; |
74 | Vtg.Utils.trace ("completing word: '%s'", word); |
75 | - if (!Vtg.StringUtils.is_null_or_empty (word) |
76 | - && this.completion.try_acquire_ast (out ast)) |
77 | + if (!Vtg.StringUtils.is_null_or_empty (word)) |
78 | { |
79 | Afrodite.QueryOptions options = this.get_options_for_line (text, is_assignment, is_creation); |
80 | Afrodite.QueryResult result = null; |
81 | @@ -878,7 +872,6 @@ |
82 | } |
83 | result = this.get_symbol_type_for_name (options, ast, word, text, line, col); |
84 | this.transform_result (options, result); |
85 | - this.completion.release_ast (ast); |
86 | } |
87 | else |
88 | { |
89 | @@ -895,12 +888,11 @@ |
90 | |
91 | private void lookup_visible_symbols_in_scope (string word, Afrodite.CompareMode mode) |
92 | { |
93 | - Afrodite.Ast ast = null; |
94 | + Afrodite.Ast ast = completion.ast; |
95 | Vtg.Utils.trace ("lookup_all_symbols_in_scope: mode: %s word:'%s' ", |
96 | mode == Afrodite.CompareMode.EXACT ? "exact" : "start-with", |
97 | word); |
98 | - if (!Vtg.StringUtils.is_null_or_empty (word) |
99 | - && this.completion.try_acquire_ast (out ast, 0)) |
100 | + if (!Vtg.StringUtils.is_null_or_empty (word)) |
101 | { |
102 | Vala.List<Afrodite.Symbol> results = new Vala.ArrayList<Afrodite.Symbol> (); |
103 | |
104 | @@ -929,7 +921,6 @@ |
105 | this.proposals = new List<Gtk.SourceCompletionItem> (); |
106 | append_symbols (null, results); |
107 | } |
108 | - this.completion.release_ast (ast); |
109 | } |
110 | else |
111 | { |
112 | |
113 | === modified file 'plugins/completion/afrodite-provider/afrodite/Makefile.am' |
114 | --- plugins/completion/afrodite-provider/afrodite/Makefile.am 2010-10-14 16:01:50 +0000 |
115 | +++ plugins/completion/afrodite-provider/afrodite/Makefile.am 2011-03-10 19:26:24 +0000 |
116 | @@ -61,7 +61,7 @@ |
117 | touch $@ |
118 | |
119 | libafrodite_la_LDFLAGS = \ |
120 | - -version-info 0:1:0 \ |
121 | + -version-info 1:0:0 \ |
122 | $(NULL) |
123 | |
124 | libafrodite_la_LIBADD = \ |
125 | |
126 | === modified file 'plugins/completion/afrodite-provider/afrodite/afroditetest.vala' |
127 | --- plugins/completion/afrodite-provider/afrodite/afroditetest.vala 2010-10-14 16:01:50 +0000 |
128 | +++ plugins/completion/afrodite-provider/afrodite/afroditetest.vala 2011-03-10 19:26:24 +0000 |
129 | @@ -47,10 +47,11 @@ |
130 | }; |
131 | |
132 | public class AfroditeTest.Application : Object { |
133 | + |
134 | + private MainLoop _loop; |
135 | + private Afrodite.CompletionEngine _engine; |
136 | + |
137 | public int run (string[] args) { |
138 | - int i = 0; |
139 | - int result = 0; |
140 | - |
141 | // parse options |
142 | var opt_context = new OptionContext ("- Afrodite Test"); |
143 | opt_context.set_help_enabled (true); |
144 | @@ -60,12 +61,119 @@ |
145 | } catch (Error err) { |
146 | error (_("parsing options")); |
147 | } |
148 | - |
149 | - var engine = new Afrodite.CompletionEngine ("afrodite-test-engine"); |
150 | - |
151 | + |
152 | if (option_repeat == 0) |
153 | option_repeat = 1; |
154 | - |
155 | + |
156 | + parse (); |
157 | + _loop = new MainLoop(); |
158 | + _loop.run(); |
159 | + return 0; |
160 | + } |
161 | + |
162 | + private void on_begin_parsing (CompletionEngine engine) |
163 | + { |
164 | + print ("\nAfrodite engine is parsing sources\n"); |
165 | + } |
166 | + private void on_end_parsing (CompletionEngine engine) |
167 | + { |
168 | + print ("\nAfrodite engine end parsing sources\n"); |
169 | + _loop.quit (); |
170 | + dump (engine); |
171 | + } |
172 | + |
173 | + private void dump (CompletionEngine engine) |
174 | + { |
175 | + print (": done\n\n"); |
176 | + print ("Looking for '%s' %d,%d\n\nDump follows:\n", option_symbol_name, option_line, option_column); |
177 | + while (true) |
178 | + { |
179 | + // dumping tree (just a debug facility) |
180 | + var dumper = new Afrodite.AstDumper (); |
181 | + dumper.dump (engine.ast, option_namespace); |
182 | + print ("\n"); |
183 | + |
184 | + // Query the AST |
185 | + if (option_visible_symbols != null) { |
186 | + var source = engine.ast.lookup_source_file (option_visible_symbols); |
187 | + if (source != null) { |
188 | + // get the source node at this position |
189 | + var s = engine.ast.get_symbol_for_source_and_position (source, option_line, option_column); |
190 | + if (s != null) { |
191 | + Vala.List<Symbol> syms = null; |
192 | + syms = engine.ast.lookup_visible_symbols_from_symbol (s, option_filter); |
193 | + print ("Symbols found: %d\n", syms.size); |
194 | + foreach (Symbol sym in syms) { |
195 | + print (" from %s: %s\n", sym.parent == null ? "<root>" : sym.parent.fully_qualified_name, Utils.unescape_xml_string (sym.description)); |
196 | + } |
197 | + } else { |
198 | + print ("no symbol found for position: %d-%d\n", option_line, option_column); |
199 | + } |
200 | + } else { |
201 | + print ("source file not found: %s\n", option_visible_symbols); |
202 | + } |
203 | + } else if (option_symbol_name != null) { |
204 | + // Setup query options |
205 | + QueryOptions options = QueryOptions.standard (); |
206 | + options.auto_member_binding_mode = true; |
207 | + options.compare_mode = CompareMode.EXACT; |
208 | + options.access = Afrodite.SymbolAccessibility.ANY; |
209 | + options.binding = Afrodite.MemberBinding.ANY; |
210 | + |
211 | + QueryResult sym = null; |
212 | + sym = engine.ast.get_symbol_type_for_name_and_path (options, option_symbol_name, option_files[0], option_line, option_column); |
213 | + print ("The type for '%s' is: ", option_symbol_name); |
214 | + if (!sym.is_empty) { |
215 | + foreach (ResultItem item in sym.children) { |
216 | + print ("%s\n Childs:\n", Utils.unescape_xml_string (item.symbol.description)); |
217 | + if (item.symbol.has_children) { |
218 | + int count = 0; |
219 | + // print an excerpt of the child symbols |
220 | + foreach (var child in item.symbol.children) { |
221 | + print (" %s\n", Utils.unescape_xml_string (child.description)); |
222 | + count++; |
223 | + if (count == 6) { |
224 | + print (" ......\n"); |
225 | + break; |
226 | + } |
227 | + } |
228 | + if (count < 6 && item.symbol.has_base_types) { |
229 | + foreach (var base_item in item.symbol.base_types) { |
230 | + if (base_item.unresolved || !base_item.symbol.has_children) |
231 | + continue; |
232 | + |
233 | + foreach (var child in base_item.symbol.children) { |
234 | + print (" %s\n", Utils.unescape_xml_string (child.description)); |
235 | + count++; |
236 | + if (count == 6) |
237 | + break; |
238 | + } |
239 | + |
240 | + if (count == 6) { |
241 | + print (" ......\n"); |
242 | + break; |
243 | + } |
244 | + } |
245 | + } |
246 | + } |
247 | + } |
248 | + } else { |
249 | + print ("unresolved :(\n"); |
250 | + } |
251 | + } |
252 | + break; |
253 | + } |
254 | + |
255 | + print ("done\n"); |
256 | + } |
257 | + |
258 | + private void parse () { |
259 | + int i = 0; |
260 | + |
261 | + _engine = new Afrodite.CompletionEngine ("afrodite-test-engine"); |
262 | + _engine.begin_parsing.connect (this.on_begin_parsing); |
263 | + _engine.end_parsing.connect (this.on_end_parsing); |
264 | + |
265 | for(int repeat = 0; repeat < option_repeat; repeat++) { |
266 | print ("Adding sources (%d):\n", repeat); |
267 | i = 0; |
268 | @@ -82,118 +190,17 @@ |
269 | } |
270 | source.content = buffer; |
271 | source.path = "live-buffer.vala"; |
272 | - engine.queue_source (source); |
273 | + _engine.queue_source (source); |
274 | } else { |
275 | - engine.queue_sourcefile (filename); |
276 | - } |
277 | - i++; |
278 | - } |
279 | - |
280 | - print ("\nAfrodite engine is parsing sources (%d)", repeat); |
281 | - // Wait for the engine to complete the parsing |
282 | - i = 0; |
283 | - while (engine.is_parsing) |
284 | - { |
285 | - if (i % 10 == 0) |
286 | - print ("."); |
287 | - Thread.usleep (1 * 250000); |
288 | - i++; |
289 | - } |
290 | - } |
291 | - |
292 | - Afrodite.Ast ast; |
293 | - print (": done\n\n"); |
294 | - print ("Looking for '%s' %d,%d\n\nDump follows:\n", option_symbol_name, option_line, option_column); |
295 | - while (true) |
296 | - { |
297 | - // try to acquire ast |
298 | - if (engine.try_acquire_ast (out ast)) { |
299 | - // dumping tree (just a debug facility) |
300 | - var dumper = new Afrodite.AstDumper (); |
301 | - dumper.dump (ast, option_namespace); |
302 | - print ("\n"); |
303 | - |
304 | - // Query the AST |
305 | - if (option_visible_symbols != null) { |
306 | - var source = ast.lookup_source_file (option_visible_symbols); |
307 | - if (source != null) { |
308 | - // get the source node at this position |
309 | - var s = ast.get_symbol_for_source_and_position (source, option_line, option_column); |
310 | - if (s != null) { |
311 | - Vala.List<Symbol> syms = null; |
312 | - syms = ast.lookup_visible_symbols_from_symbol (s, option_filter); |
313 | - print ("Symbols found: %d\n", syms.size); |
314 | - foreach (Symbol sym in syms) { |
315 | - print (" from %s: %s\n", sym.parent == null ? "<root>" : sym.parent.fully_qualified_name, Utils.unescape_xml_string (sym.description)); |
316 | - } |
317 | - } else { |
318 | - print ("no symbol found for position: %d-%d\n", option_line, option_column); |
319 | - } |
320 | - } else { |
321 | - print ("source file not found: %s\n", option_visible_symbols); |
322 | - } |
323 | - } else if (option_symbol_name != null) { |
324 | - // Setup query options |
325 | - QueryOptions options = QueryOptions.standard (); |
326 | - options.auto_member_binding_mode = true; |
327 | - options.compare_mode = CompareMode.EXACT; |
328 | - options.access = Afrodite.SymbolAccessibility.ANY; |
329 | - options.binding = Afrodite.MemberBinding.ANY; |
330 | - |
331 | - QueryResult sym = null; |
332 | - sym = ast.get_symbol_type_for_name_and_path (options, option_symbol_name, option_files[0], option_line, option_column); |
333 | - print ("The type for '%s' is: ", option_symbol_name); |
334 | - if (!sym.is_empty) { |
335 | - foreach (ResultItem item in sym.children) { |
336 | - print ("%s\n Childs:\n", Utils.unescape_xml_string (item.symbol.description)); |
337 | - if (item.symbol.has_children) { |
338 | - int count = 0; |
339 | - // print an excerpt of the child symbols |
340 | - foreach (var child in item.symbol.children) { |
341 | - print (" %s\n", Utils.unescape_xml_string (child.description)); |
342 | - count++; |
343 | - if (count == 6) { |
344 | - print (" ......\n"); |
345 | - break; |
346 | - } |
347 | - } |
348 | - if (count < 6 && item.symbol.has_base_types) { |
349 | - foreach (var base_item in item.symbol.base_types) { |
350 | - if (base_item.unresolved || !base_item.symbol.has_children) |
351 | - continue; |
352 | - |
353 | - foreach (var child in base_item.symbol.children) { |
354 | - print (" %s\n", Utils.unescape_xml_string (child.description)); |
355 | - count++; |
356 | - if (count == 6) |
357 | - break; |
358 | - } |
359 | - |
360 | - if (count == 6) { |
361 | - print (" ......\n"); |
362 | - break; |
363 | - } |
364 | - } |
365 | - } |
366 | - } |
367 | - } |
368 | - } else { |
369 | - print ("unresolved :(\n"); |
370 | - result = 1; |
371 | - } |
372 | - } |
373 | - engine.release_ast (ast); |
374 | - break; |
375 | - } |
376 | - } |
377 | - |
378 | - print ("done\n"); |
379 | - return result; |
380 | + _engine.queue_sourcefile (filename); |
381 | + } |
382 | + i++; |
383 | + } |
384 | + } |
385 | } |
386 | |
387 | static int main (string[] args) { |
388 | var application = new Application (); |
389 | - application.run (args); |
390 | - return 0; |
391 | + return application.run (args); |
392 | } |
393 | } |
394 | |
395 | === modified file 'plugins/completion/afrodite-provider/afrodite/ast.vala' |
396 | --- plugins/completion/afrodite-provider/afrodite/ast.vala 2010-10-14 16:01:50 +0000 |
397 | +++ plugins/completion/afrodite-provider/afrodite/ast.vala 2011-03-10 19:26:24 +0000 |
398 | @@ -26,32 +26,17 @@ |
399 | { |
400 | public class Ast |
401 | { |
402 | - |
403 | -#if DEBUG |
404 | - // debug utility to dump leaked symbols when destroying a source file |
405 | - public static Vala.List<unowned Symbol> leaked_symbols = new Vala.ArrayList<unowned Symbol>(); |
406 | -#endif |
407 | public Vala.HashMap<string, unowned Symbol> symbols = new Vala.HashMap <string, unowned Symbol>(GLib.str_hash, GLib.str_equal); |
408 | - |
409 | + public Vala.List<unowned Symbol> unresolved_symbols = new Vala.ArrayList<unowned Symbol>(); |
410 | + |
411 | private Symbol _root = new Symbol (null, null); |
412 | |
413 | ~Ast () |
414 | { |
415 | Utils.trace ("Ast destroy"); |
416 | -#if DEBUG |
417 | - Utils.trace (" symbol count before destroy %d", leaked_symbols.size); |
418 | -#endif |
419 | // destroy the root symbol |
420 | _root = null; |
421 | source_files = null;// source have to be destroyes after root symbol |
422 | - |
423 | -#if DEBUG |
424 | - Utils.trace (" symbol count after destroy %d", leaked_symbols.size); |
425 | - if (leaked_symbols.size > 0) { |
426 | - this.dump_leaks (); |
427 | - } |
428 | -#endif |
429 | - |
430 | Utils.trace ("Ast destroyed"); |
431 | } |
432 | |
433 | @@ -69,11 +54,11 @@ |
434 | |
435 | public Vala.List<SourceFile> source_files { get; set; } |
436 | |
437 | - public Symbol? lookup (string fully_qualified_name, out Symbol? parent) |
438 | + public Symbol? lookup (string fully_qualified_name) |
439 | { |
440 | Symbol result = null; |
441 | |
442 | - parent = _root; |
443 | + Symbol parent = _root; |
444 | if (_root.has_children) { |
445 | result = lookup_symbol (fully_qualified_name, _root, ref parent, CompareMode.EXACT); |
446 | } |
447 | @@ -148,7 +133,6 @@ |
448 | */ |
449 | |
450 | foreach (SourceFile file in source_files) { |
451 | - |
452 | if (file.filename == filename) { |
453 | return file; |
454 | } |
455 | @@ -582,10 +566,11 @@ |
456 | // search in using directives |
457 | if (source.has_using_directives) { |
458 | foreach (DataType u in source.using_directives) { |
459 | - Symbol parent; |
460 | - |
461 | - sym = lookup (u.type_name, out parent); |
462 | + |
463 | + |
464 | + sym = lookup (u.type_name); |
465 | if (sym != null) { |
466 | + Symbol parent = sym.parent; |
467 | if (compare_symbol_names (sym.name, name, mode)) { |
468 | // is a reference to a namespace |
469 | return sym; |
470 | @@ -606,7 +591,7 @@ |
471 | public Symbol? get_symbol_for_source_and_position (SourceFile source, int line, int column) |
472 | { |
473 | Symbol result = null; |
474 | - SourceReference result_sr = null; |
475 | + unowned SourceReference result_sr = null; |
476 | |
477 | if (source.has_symbols) { |
478 | // base 0 |
479 | @@ -638,19 +623,5 @@ |
480 | |
481 | return result; |
482 | } |
483 | - |
484 | -#if DEBUG |
485 | - private void dump_leaks () |
486 | - { |
487 | - foreach (Symbol s in leaked_symbols) { |
488 | - Utils.trace (" -- leaked symbol %s (%p), parent %s (%p), generic_parent %s (%p) childs %d, refcount %u", |
489 | - s.fully_qualified_name, s, |
490 | - s.parent == null ? "null" : s.parent.fully_qualified_name, s.parent, |
491 | - s.generic_parent == null ? "null" : s.generic_parent.fully_qualified_name, s.generic_parent, |
492 | - s.has_children ? s.children.size : 0, |
493 | - s.ref_count); |
494 | - } |
495 | - } |
496 | -#endif |
497 | } |
498 | } |
499 | |
500 | === modified file 'plugins/completion/afrodite-provider/afrodite/astdumper.vala' |
501 | --- plugins/completion/afrodite-provider/afrodite/astdumper.vala 2010-09-03 21:40:48 +0000 |
502 | +++ plugins/completion/afrodite-provider/afrodite/astdumper.vala 2011-03-10 19:26:24 +0000 |
503 | @@ -140,7 +140,7 @@ |
504 | inc_pad (); |
505 | print ("%slocal variables\n", pad); |
506 | foreach (DataType local in symbol.local_variables) { |
507 | - var sr = local.source_reference; |
508 | + unowned SourceReference sr = local.source_reference; |
509 | print ("%s %s - [(%d - %d) %s]\n", |
510 | pad, |
511 | Utils.unescape_xml_string (local.description), |
512 | |
513 | === modified file 'plugins/completion/afrodite-provider/afrodite/astmerger.vala' |
514 | --- plugins/completion/afrodite-provider/afrodite/astmerger.vala 2010-12-30 07:38:50 +0000 |
515 | +++ plugins/completion/afrodite-provider/afrodite/astmerger.vala 2011-03-10 19:26:24 +0000 |
516 | @@ -28,40 +28,135 @@ |
517 | { |
518 | Afrodite.Symbol _current = null; |
519 | Afrodite.DataType _current_type = null; |
520 | - Afrodite.SourceReference _current_sr = null; |
521 | + unowned Afrodite.SourceReference _current_sr = null; |
522 | Afrodite.SourceFile _source_file = null; |
523 | Afrodite.DataType _inferred_type = null; |
524 | Vala.Literal _last_literal = null; |
525 | |
526 | string _vala_symbol_fqn = null; |
527 | bool _merge_glib = true; |
528 | - int _child_count = 0; |
529 | - |
530 | + |
531 | private Afrodite.Ast _ast = null; |
532 | - |
533 | + |
534 | public AstMerger (Afrodite.Ast ast) |
535 | { |
536 | this._ast = ast; |
537 | } |
538 | |
539 | - public void merge_vala_context (Vala.SourceFile source, CodeContext context, bool merge_glib = false) |
540 | + public async void merge_vala_context (Vala.SourceFile source, CodeContext context, bool merge_glib = false) |
541 | { |
542 | _merge_glib = merge_glib; |
543 | _vala_symbol_fqn = null; |
544 | _current_type = null; |
545 | - _child_count = 0; |
546 | _current = _ast.root; |
547 | assert (_ast.lookup_source_file (source.filename) == null); |
548 | |
549 | //debug ("COMPLETING FILE %s", source.filename); |
550 | _source_file = _ast.add_source_file (source.filename); |
551 | foreach (UsingDirective u in source.current_using_directives) { |
552 | - _source_file.add_using_directive (u.namespace_symbol.get_full_name ()); |
553 | - } |
554 | - context.root.accept_children (this); |
555 | - } |
556 | - |
557 | - public void remove_source_filename (string filename) |
558 | + _source_file.add_using_directive (u.namespace_symbol.to_string ()); |
559 | + } |
560 | + yield visit_namespace_sliced (context.root); |
561 | + } |
562 | + |
563 | + public async void visit_namespace_sliced (Namespace ns) |
564 | + { |
565 | + var prev_vala_fqn = _vala_symbol_fqn; |
566 | + var prev = _current; |
567 | + unowned SourceReference prev_sr = _current_sr; |
568 | + |
569 | + if (ns.name != null) |
570 | + _current = visit_symbol (ns, out _current_sr); |
571 | + |
572 | + foreach (Enum en in ns.get_enums ()) { |
573 | + en.accept (this); |
574 | + } |
575 | + |
576 | + foreach (ErrorDomain edomain in ns.get_error_domains ()) { |
577 | + edomain.accept (this); |
578 | + } |
579 | + |
580 | + foreach (Vala.Namespace n in ns.get_namespaces ()) { |
581 | + yield visit_namespace_sliced (n); |
582 | + } |
583 | + |
584 | + foreach (Vala.Class cl in ns.get_classes ()) { |
585 | + yield visit_class_sliced (cl); |
586 | + } |
587 | + |
588 | + foreach (Interface iface in ns.get_interfaces ()) { |
589 | + yield visit_interface_sliced (iface); |
590 | + } |
591 | + |
592 | + foreach (Struct st in ns.get_structs ()) { |
593 | + yield visit_struct_sliced (st); |
594 | + } |
595 | + |
596 | + foreach (Delegate d in ns.get_delegates ()) { |
597 | + d.accept (this); |
598 | + } |
599 | + |
600 | + foreach (Constant c in ns.get_constants ()) { |
601 | + c.accept (this); |
602 | + } |
603 | + |
604 | + foreach (Field f in ns.get_fields ()) { |
605 | + f.accept (this); |
606 | + } |
607 | + |
608 | + foreach (Method m in ns.get_methods ()) { |
609 | + m.accept (this); |
610 | + } |
611 | + |
612 | + _current = prev; |
613 | + _current_sr = prev_sr; |
614 | + _vala_symbol_fqn = prev_vala_fqn; |
615 | + } |
616 | + |
617 | + public async void visit_class_sliced (Class c) |
618 | + { |
619 | + visit_class (c); |
620 | + } |
621 | + |
622 | + public async void visit_struct_sliced (Struct st) |
623 | + { |
624 | + visit_struct (st); |
625 | + } |
626 | + |
627 | + public async void visit_interface_sliced (Interface iface) |
628 | + { |
629 | + visit_interface (iface); |
630 | + } |
631 | + |
632 | + public override void visit_class (Class c) |
633 | + { |
634 | + var prev_vala_fqn = _vala_symbol_fqn; |
635 | + var prev = _current; |
636 | + unowned SourceReference prev_sr = _current_sr; |
637 | + |
638 | + _current = visit_symbol (c, out _current_sr); |
639 | + _current.is_abstract = c.is_abstract; |
640 | + c.accept_children (this); |
641 | + |
642 | + _current = prev; |
643 | + _current_sr = prev_sr; |
644 | + _vala_symbol_fqn = prev_vala_fqn; |
645 | + } |
646 | + |
647 | + public override void visit_struct (Struct s) |
648 | + { |
649 | + var prev_vala_fqn = _vala_symbol_fqn; |
650 | + var prev = _current; |
651 | + unowned SourceReference prev_sr = _current_sr; |
652 | + |
653 | + _current = visit_symbol (s, out _current_sr); |
654 | + s.accept_children (this); |
655 | + _current = prev; |
656 | + _current_sr = prev_sr; |
657 | + _vala_symbol_fqn = prev_vala_fqn; |
658 | + } |
659 | + |
660 | + public async void remove_source_filename (string filename) |
661 | { |
662 | var source = _ast.lookup_source_file (filename); |
663 | assert (source != null); |
664 | @@ -69,65 +164,62 @@ |
665 | _ast.remove_source (source); |
666 | } |
667 | |
668 | - private Afrodite.Symbol visit_symbol (Vala.Symbol s, out Afrodite.SourceReference source_reference) |
669 | + private Afrodite.Symbol visit_symbol (Vala.Symbol s, out unowned Afrodite.SourceReference source_reference) |
670 | { |
671 | Afrodite.Symbol symbol; |
672 | |
673 | set_fqn (s.name); |
674 | - //symbol = _ast.lookup (_vala_symbol_fqn, out parent); |
675 | - //assert (parent != null); |
676 | - symbol = _ast.symbols.@get (_vala_symbol_fqn); |
677 | |
678 | - if (symbol == null) { |
679 | + //NOTE: usually we should always add symbols but |
680 | + // we should merge namespaces content. |
681 | + // This must be changed whenever vala will support |
682 | + // partial classes. |
683 | + if (s.type_name != "ValaNamespace") { |
684 | symbol = add_symbol (s, out source_reference); |
685 | - //Utils.trace ("adding %s to source %s", symbol.fully_qualified_name, _source_file.filename); |
686 | _current.add_child (symbol); |
687 | } else { |
688 | - Afrodite.Symbol parent = symbol.parent; |
689 | - //NOTE: see if we should replace the symbol |
690 | - // we should replace it if is not a namespace |
691 | - // this can change whenever vala will support |
692 | - // partial classes |
693 | - bool replace = s.type_name != "ValaNamespace"; |
694 | - if (replace) { |
695 | - parent.remove_child (symbol); |
696 | + symbol = _ast.lookup (_vala_symbol_fqn); |
697 | + if (symbol == null) { |
698 | symbol = add_symbol (s, out source_reference); |
699 | - parent.add_child (symbol); |
700 | + //Utils.trace ("adding %s to source %s", symbol.fully_qualified_name, _source_file.filename); |
701 | + _current.add_child (symbol); |
702 | } else { |
703 | + source_reference = symbol.lookup_source_reference_filename (_source_file.filename); |
704 | // add one more source reference to the symbol |
705 | - source_reference = symbol.lookup_source_reference_filename (_source_file.filename); |
706 | if (source_reference == null) { |
707 | - source_reference = create_source_reference (s); |
708 | - symbol.add_source_reference (source_reference); |
709 | + var sr = create_source_reference (s); |
710 | + symbol.add_source_reference (sr); |
711 | + source_reference = sr; |
712 | //Utils.trace ("adding source reference %s to source %s", symbol.fully_qualified_name, _source_file.filename); |
713 | _source_file.add_symbol (symbol); |
714 | } else { |
715 | - warning ("two sources with the same name were merged: %s", _source_file.filename); |
716 | + warning ("two sources with the same name were merged %s: %s", symbol.fully_qualified_name, _source_file.filename); |
717 | } |
718 | } |
719 | } |
720 | - |
721 | return symbol; |
722 | } |
723 | |
724 | - private Afrodite.Symbol add_symbol (Vala.Symbol s, out Afrodite.SourceReference source_ref, int last_line = 0, int last_column = 0) |
725 | + private Afrodite.Symbol add_symbol (Vala.Symbol s, out unowned Afrodite.SourceReference source_ref, int last_line = 0, int last_column = 0) |
726 | { |
727 | var symbol = new Afrodite.Symbol (_vala_symbol_fqn, s.type_name); |
728 | if (symbol.lookup_source_reference_filename (_source_file.filename) == null) { |
729 | - source_ref = create_source_reference (s, last_line, last_column); |
730 | - symbol.add_source_reference (source_ref); |
731 | + var sr = create_source_reference (s, last_line, last_column); |
732 | + symbol.add_source_reference (sr); |
733 | + source_ref = sr; |
734 | } |
735 | symbol.access = get_vala_symbol_access (s.access); |
736 | _source_file.add_symbol (symbol); |
737 | return symbol; |
738 | } |
739 | |
740 | - private Afrodite.Symbol add_codenode (string type_name, Vala.CodeNode c, out Afrodite.SourceReference source_ref, int last_line = 0, int last_column = 0) |
741 | + private Afrodite.Symbol add_codenode (string type_name, Vala.CodeNode c, out unowned Afrodite.SourceReference source_ref, int last_line = 0, int last_column = 0) |
742 | { |
743 | var symbol = new Afrodite.Symbol (_vala_symbol_fqn, type_name); |
744 | if (symbol.lookup_source_reference_filename (_source_file.filename) == null) { |
745 | - source_ref = create_source_reference (c, last_line, last_column); |
746 | - symbol.add_source_reference (source_ref); |
747 | + var sr = create_source_reference (c, last_line, last_column); |
748 | + symbol.add_source_reference (sr); |
749 | + source_ref = sr; |
750 | } |
751 | symbol.access = Afrodite.SymbolAccessibility.PRIVATE; |
752 | _source_file.add_symbol (symbol); |
753 | @@ -198,58 +290,11 @@ |
754 | } |
755 | } |
756 | |
757 | - public override void visit_namespace (Namespace ns) |
758 | - { |
759 | - var prev_vala_fqn = _vala_symbol_fqn; |
760 | - var prev = _current; |
761 | - var prev_sr = _current_sr; |
762 | - var prev_child_count = _child_count; |
763 | - |
764 | - _current = visit_symbol (ns, out _current_sr); |
765 | - ns.accept_children (this); |
766 | - |
767 | - _child_count = prev_child_count; |
768 | - _current = prev; |
769 | - _current_sr = prev_sr; |
770 | - _vala_symbol_fqn = prev_vala_fqn; |
771 | - } |
772 | - |
773 | - public override void visit_class (Class c) |
774 | - { |
775 | - _child_count++; |
776 | - var prev_vala_fqn = _vala_symbol_fqn; |
777 | - var prev = _current; |
778 | - var prev_sr = _current_sr; |
779 | - |
780 | - _current = visit_symbol (c, out _current_sr); |
781 | - _current.is_abstract = c.is_abstract; |
782 | - c.accept_children (this); |
783 | - |
784 | - _current = prev; |
785 | - _current_sr = prev_sr; |
786 | - _vala_symbol_fqn = prev_vala_fqn; |
787 | - } |
788 | - |
789 | - public override void visit_struct (Struct s) |
790 | - { |
791 | - _child_count++; |
792 | - var prev_vala_fqn = _vala_symbol_fqn; |
793 | - var prev = _current; |
794 | - var prev_sr = _current_sr; |
795 | - |
796 | - _current = visit_symbol (s, out _current_sr); |
797 | - s.accept_children (this); |
798 | - _current = prev; |
799 | - _current_sr = prev_sr; |
800 | - _vala_symbol_fqn = prev_vala_fqn; |
801 | - } |
802 | - |
803 | public override void visit_interface (Interface iface) |
804 | { |
805 | - _child_count++; |
806 | var prev_vala_fqn = _vala_symbol_fqn; |
807 | var prev = _current; |
808 | - var prev_sr = _current_sr; |
809 | + unowned SourceReference prev_sr = _current_sr; |
810 | |
811 | _current = visit_symbol (iface, out _current_sr); |
812 | iface.accept_children (this); |
813 | @@ -258,6 +303,7 @@ |
814 | _vala_symbol_fqn = prev_vala_fqn; |
815 | } |
816 | |
817 | + /* |
818 | public override void visit_expression_statement (Vala.ExpressionStatement e) |
819 | { |
820 | e.accept_children (this); |
821 | @@ -268,13 +314,17 @@ |
822 | //Utils.trace ("visit method call: %s", c.call.type_name); |
823 | c.accept_children (this); |
824 | } |
825 | + */ |
826 | |
827 | public override void visit_method (Method m) |
828 | { |
829 | - _child_count++; |
830 | + //var timer = new Timer(); |
831 | + //timer.start (); |
832 | + //Utils.trace ("visit method %s", m.name); |
833 | + |
834 | var prev_vala_fqn = _vala_symbol_fqn; |
835 | var prev = _current; |
836 | - var prev_sr = _current_sr; |
837 | + unowned SourceReference prev_sr = _current_sr; |
838 | |
839 | set_fqn (m.name); |
840 | int last_line = 0; |
841 | @@ -301,18 +351,30 @@ |
842 | |
843 | _current = s; |
844 | visit_type_for_generics (m.return_type, s.return_type); |
845 | - m.accept_children (this); |
846 | - |
847 | + //Utils.trace ("visit method (symbol) %s: %f", m.name, timer.elapsed()); |
848 | + foreach (TypeParameter p in m.get_type_parameters ()) { |
849 | + p.accept (this); |
850 | + } |
851 | + //Utils.trace ("visit method (typeparam) %s: %f", m.name, timer.elapsed()); |
852 | + foreach (Vala.Parameter param in m.get_parameters ()) { |
853 | + param.accept (this); |
854 | + } |
855 | + //Utils.trace ("visit method (param) %s: %f", m.name, timer.elapsed()); |
856 | + if (m.body != null) { |
857 | + m.body.accept (this); |
858 | + } |
859 | + //Utils.trace ("visit method (body) %s: %f", m.name, timer.elapsed()); |
860 | _current = prev; |
861 | _current_sr = prev_sr; |
862 | _vala_symbol_fqn = prev_vala_fqn; |
863 | + //Utils.trace ("visit method %s: %f", m.name, timer.elapsed()); |
864 | } |
865 | |
866 | public override void visit_creation_method (CreationMethod m) |
867 | { |
868 | var prev_vala_fqn = _vala_symbol_fqn; |
869 | var prev = _current; |
870 | - var prev_sr = _current_sr; |
871 | + unowned SourceReference prev_sr = _current_sr; |
872 | |
873 | set_fqn (m.name); |
874 | int last_line = 0; |
875 | @@ -339,8 +401,18 @@ |
876 | |
877 | _current = s; |
878 | visit_type_for_generics (m.return_type, s.return_type); |
879 | - m.accept_children (this); |
880 | - |
881 | + foreach (TypeParameter p in m.get_type_parameters ()) { |
882 | + p.accept (this); |
883 | + } |
884 | + |
885 | + foreach (Vala.Parameter param in m.get_parameters ()) { |
886 | + param.accept (this); |
887 | + } |
888 | + |
889 | + if (m.body != null) { |
890 | + m.body.accept (this); |
891 | + } |
892 | + |
893 | _current = prev; |
894 | _current_sr = prev_sr; |
895 | _vala_symbol_fqn = prev_vala_fqn; |
896 | @@ -350,7 +422,7 @@ |
897 | { |
898 | var prev_vala_fqn = _vala_symbol_fqn; |
899 | var prev = _current; |
900 | - var prev_sr = _current_sr; |
901 | + unowned SourceReference prev_sr = _current_sr; |
902 | |
903 | set_fqn ("constructor:%s".printf(_current.fully_qualified_name)); |
904 | int last_line = 0; |
905 | @@ -363,8 +435,9 @@ |
906 | _current.add_child (s); |
907 | |
908 | _current = s; |
909 | - m.accept_children (this); |
910 | - |
911 | + if (m.body != null) { |
912 | + m.body.accept (this); |
913 | + } |
914 | _current = prev; |
915 | _current_sr = prev_sr; |
916 | _vala_symbol_fqn = prev_vala_fqn; |
917 | @@ -374,7 +447,7 @@ |
918 | { |
919 | var prev_vala_fqn = _vala_symbol_fqn; |
920 | var prev = _current; |
921 | - var prev_sr = _current_sr; |
922 | + unowned SourceReference prev_sr = _current_sr; |
923 | |
924 | set_fqn ("destructor:%s".printf(_current.fully_qualified_name)); |
925 | int last_line = 0; |
926 | @@ -387,7 +460,10 @@ |
927 | _current.add_child (s); |
928 | |
929 | _current = s; |
930 | - m.accept_children (this); |
931 | + if (m.body != null) { |
932 | + m.body.accept (this); |
933 | + } |
934 | + |
935 | _current = prev; |
936 | _current_sr = prev_sr; |
937 | _vala_symbol_fqn = prev_vala_fqn; |
938 | @@ -397,7 +473,7 @@ |
939 | { |
940 | var prev_vala_fqn = _vala_symbol_fqn; |
941 | var prev = _current; |
942 | - var prev_sr = _current_sr; |
943 | + unowned SourceReference prev_sr = _current_sr; |
944 | |
945 | set_fqn (ev.name); |
946 | var sym = add_symbol (ev, out _current_sr); |
947 | @@ -412,16 +488,27 @@ |
948 | |
949 | public override void visit_enum (Vala.Enum e) |
950 | { |
951 | - _child_count++; |
952 | var prev_vala_fqn = _vala_symbol_fqn; |
953 | var prev = _current; |
954 | - var prev_sr = _current_sr; |
955 | + unowned SourceReference prev_sr = _current_sr; |
956 | |
957 | set_fqn (e.name); |
958 | var s = add_symbol (e, out _current_sr); |
959 | _current.add_child (s); |
960 | _current = s; |
961 | - e.accept_children (this); |
962 | + |
963 | + foreach (Vala.EnumValue value in e.get_values ()) { |
964 | + value.accept (this); |
965 | + } |
966 | + |
967 | + foreach (Method m in e.get_methods ()) { |
968 | + m.accept (this); |
969 | + } |
970 | + |
971 | + foreach (Constant c in e.get_constants ()) { |
972 | + c.accept (this); |
973 | + } |
974 | + |
975 | _current = prev; |
976 | _current_sr = prev_sr; |
977 | _vala_symbol_fqn = prev_vala_fqn; |
978 | @@ -429,16 +516,23 @@ |
979 | |
980 | public override void visit_delegate (Delegate d) |
981 | { |
982 | - _child_count++; |
983 | var prev_vala_fqn = _vala_symbol_fqn; |
984 | var prev = _current; |
985 | - var prev_sr = _current_sr; |
986 | + unowned SourceReference prev_sr = _current_sr; |
987 | |
988 | set_fqn (d.name); |
989 | var sym = add_symbol (d, out _current_sr); |
990 | + sym.return_type = new DataType (d.return_type.to_string ()); |
991 | _current.add_child (sym); |
992 | _current = sym; |
993 | - d.accept_children (this); |
994 | + |
995 | + foreach (TypeParameter p in d.get_type_parameters ()) { |
996 | + p.accept (this); |
997 | + } |
998 | + foreach (Vala.Parameter param in d.get_parameters ()) { |
999 | + param.accept (this); |
1000 | + } |
1001 | + |
1002 | _current = prev; |
1003 | _current_sr = prev_sr; |
1004 | _vala_symbol_fqn = prev_vala_fqn; |
1005 | @@ -446,10 +540,9 @@ |
1006 | |
1007 | public override void visit_signal (Vala.Signal s) |
1008 | { |
1009 | - _child_count++; |
1010 | var prev_vala_fqn = _vala_symbol_fqn; |
1011 | var prev = _current; |
1012 | - var prev_sr = _current_sr; |
1013 | + unowned SourceReference prev_sr = _current_sr; |
1014 | |
1015 | set_fqn (s.name); |
1016 | var sym = add_symbol (s, out _current_sr); |
1017 | @@ -457,7 +550,16 @@ |
1018 | sym.is_virtual = s.is_virtual; |
1019 | _current.add_child (sym); |
1020 | _current = sym; |
1021 | - s.accept_children (this); |
1022 | + |
1023 | + foreach (Vala.Parameter param in s.get_parameters ()) { |
1024 | + param.accept (this); |
1025 | + } |
1026 | + if (s.default_handler == null && s.body != null) { |
1027 | + s.body.accept (this); |
1028 | + } else if (s.default_handler != null) { |
1029 | + s.default_handler.accept (this); |
1030 | + } |
1031 | + |
1032 | _current = prev; |
1033 | _current_sr = prev_sr; |
1034 | _vala_symbol_fqn = prev_vala_fqn; |
1035 | @@ -465,10 +567,9 @@ |
1036 | |
1037 | public override void visit_field (Field f) |
1038 | { |
1039 | - _child_count++; |
1040 | var prev_vala_fqn = _vala_symbol_fqn; |
1041 | var prev = _current; |
1042 | - var prev_sr = _current_sr; |
1043 | + unowned SourceReference prev_sr = _current_sr; |
1044 | |
1045 | |
1046 | set_fqn (f.name); |
1047 | @@ -494,10 +595,9 @@ |
1048 | |
1049 | public override void visit_constant (Vala.Constant c) |
1050 | { |
1051 | - _child_count++; |
1052 | var prev_vala_fqn = _vala_symbol_fqn; |
1053 | var prev = _current; |
1054 | - var prev_sr = _current_sr; |
1055 | + unowned SourceReference prev_sr = _current_sr; |
1056 | |
1057 | set_fqn (c.name); |
1058 | var s = add_symbol (c, out _current_sr); |
1059 | @@ -512,10 +612,9 @@ |
1060 | |
1061 | public override void visit_property (Property p) |
1062 | { |
1063 | - _child_count++; |
1064 | var prev_vala_fqn = _vala_symbol_fqn; |
1065 | var prev = _current; |
1066 | - var prev_sr = _current_sr; |
1067 | + unowned SourceReference prev_sr = _current_sr; |
1068 | |
1069 | set_fqn (p.name); |
1070 | var s = add_symbol (p, out _current_sr); |
1071 | @@ -533,7 +632,17 @@ |
1072 | _current.add_child (s); |
1073 | |
1074 | _current = s; |
1075 | - p.accept_children (this); |
1076 | + if (p.get_accessor != null) { |
1077 | + p.get_accessor.accept (this); |
1078 | + } |
1079 | + if (p.set_accessor != null) { |
1080 | + p.set_accessor.accept (this); |
1081 | + } |
1082 | + |
1083 | + if (p.initializer != null) { |
1084 | + p.initializer.accept (this); |
1085 | + } |
1086 | + |
1087 | _current = prev; |
1088 | _current_sr = prev_sr; |
1089 | _vala_symbol_fqn = prev_vala_fqn; |
1090 | @@ -544,7 +653,7 @@ |
1091 | this.visit_scoped_codenode (a.readable ? "get" : "set", a, a.body); |
1092 | /* |
1093 | var prev = _current; |
1094 | - var prev_sr = _current_sr; |
1095 | + unowned SourceReference prev_sr = _current_sr; |
1096 | |
1097 | if (a.body != null |
1098 | && a.body.source_reference != null |
1099 | @@ -559,17 +668,23 @@ |
1100 | |
1101 | public override void visit_error_domain (ErrorDomain ed) |
1102 | { |
1103 | - _child_count++; |
1104 | var prev_vala_fqn = _vala_symbol_fqn; |
1105 | var prev = _current; |
1106 | - var prev_sr = _current_sr; |
1107 | + unowned SourceReference prev_sr = _current_sr; |
1108 | |
1109 | set_fqn (ed.name); |
1110 | var s = add_symbol (ed, out _current_sr); |
1111 | _current.add_child (s); |
1112 | |
1113 | _current = s; |
1114 | - ed.accept_children (this); |
1115 | + |
1116 | + foreach (ErrorCode ecode in ed.get_codes()) { |
1117 | + ecode.accept (this); |
1118 | + } |
1119 | + foreach (Method m in ed.get_methods ()) { |
1120 | + m.accept (this); |
1121 | + } |
1122 | + |
1123 | |
1124 | _current = prev; |
1125 | _current_sr = prev_sr; |
1126 | @@ -580,7 +695,7 @@ |
1127 | { |
1128 | var prev_vala_fqn = _vala_symbol_fqn; |
1129 | var prev = _current; |
1130 | - var prev_sr = _current_sr; |
1131 | + unowned SourceReference prev_sr = _current_sr; |
1132 | |
1133 | set_fqn (ecode.name); |
1134 | var s = add_symbol (ecode, out _current_sr); |
1135 | @@ -649,17 +764,14 @@ |
1136 | { |
1137 | var prev_vala_fqn = _vala_symbol_fqn; |
1138 | var prev = _current; |
1139 | - |
1140 | + |
1141 | set_fqn (local.name); |
1142 | DataType s = new DataType ("", local.name); |
1143 | if (local.variable_type != null) { |
1144 | s.type_name = get_datatype_typename (local.variable_type); |
1145 | - } else if (local.variable_type == null && local.initializer != null) { |
1146 | - // try to resolve local variable type from initializers |
1147 | - var prev_inferred_type = _inferred_type; |
1148 | - _inferred_type = s; |
1149 | + } else if (local.variable_type == null) { |
1150 | //Utils.trace ("infer from init '%s': %s", s.name, local.initializer.type_name); |
1151 | - |
1152 | + /* |
1153 | if (local.initializer is ObjectCreationExpression) { |
1154 | //debug ("START: initialization %s from %s: %s", local.name, s.name, _inferred_type.type_name); |
1155 | var obj_initializer = (ObjectCreationExpression) local.initializer; |
1156 | @@ -667,12 +779,22 @@ |
1157 | //debug ("END: initialization done %s", _inferred_type.type_name); |
1158 | } else if (local.initializer is MethodCall) { |
1159 | //Utils.trace ("method call: %s", s.name); |
1160 | - ((MethodCall) local.initializer).call.accept (this); // this avoid visit parameters of method calls |
1161 | + var call = ((MethodCall) local.initializer); |
1162 | + Utils.trace ("method call: %s -> %s %s", local.name, call.to_string (), call.call.type_name); |
1163 | + var ma = call.call as MemberAccess; |
1164 | + if (true || ma == null) |
1165 | + call.call.accept (this); // this avoid visit parameters of method calls |
1166 | + else { |
1167 | + |
1168 | + Utils.trace ("ma inner: %s", ma.member_name); |
1169 | + } |
1170 | + Utils.trace ("AFTER: %s", s.type_name); |
1171 | + //breakpoint(); |
1172 | } else if (local.initializer is BinaryExpression) { |
1173 | ((BinaryExpression) local.initializer).accept_children (this); |
1174 | } else if (local.initializer is CastExpression) { |
1175 | var cast_expr = (CastExpression)local.initializer; |
1176 | - cast_expr.accept (this); |
1177 | + //cast_expr.accept (this); |
1178 | if (cast_expr.type_reference != null) |
1179 | { |
1180 | s.type_name = get_datatype_typename (cast_expr.type_reference); |
1181 | @@ -680,13 +802,34 @@ |
1182 | } else if (local.initializer is ArrayCreationExpression) { |
1183 | //Utils.trace ("ArrayCreationExpression infer from init '%s' %s", s.name, local.initializer.type_name); |
1184 | var ac = (ArrayCreationExpression) local.initializer; |
1185 | - ac.accept_children (this); |
1186 | s.is_array = true; |
1187 | + if (ac.element_type == null) { |
1188 | + if (ac.initializer_list != null) { |
1189 | + ac.initializer_list.accept (this); |
1190 | + } |
1191 | + } |
1192 | s.type_name = get_datatype_typename (ac.element_type); |
1193 | //Utils.trace ("init type %s: %s %s", local.name, s.type_name, ac.element_type.type_name); |
1194 | } else { |
1195 | - local.accept_children (this); |
1196 | - } |
1197 | + if (local.initializer != null) { |
1198 | + local.initializer.accept (this); |
1199 | + } |
1200 | + } |
1201 | + */ |
1202 | + // try to resolve local variable type from initializers |
1203 | + var prev_inferred_type = _inferred_type; |
1204 | + _inferred_type = s; |
1205 | + |
1206 | + if (local.initializer != null) { |
1207 | + local.initializer.accept (this); |
1208 | + // HACK: |
1209 | + if (s.type_name != null |
1210 | + && (s.type_name.has_prefix ("this.") || s.type_name.has_prefix ("base."))) |
1211 | + { |
1212 | + s.type_name = s.type_name.substring (5); |
1213 | + } |
1214 | + } |
1215 | + |
1216 | _last_literal = null; |
1217 | //debug ("infer from init done %s", _inferred_type.type_name); |
1218 | _inferred_type = prev_inferred_type; |
1219 | @@ -734,23 +877,34 @@ |
1220 | { |
1221 | if (_inferred_type == null) |
1222 | return; |
1223 | - |
1224 | - //Utils.trace ("visit member access %s: %s", _inferred_type.type_name, expr.member_name); |
1225 | - if (_inferred_type.type_name == null || _inferred_type.type_name == "") |
1226 | - _inferred_type.type_name = expr.member_name; |
1227 | - else { |
1228 | - string member_name = null; |
1229 | - // lookup in the scope variables |
1230 | + |
1231 | + string member_name = expr.member_name; |
1232 | + //Utils.trace ("MemberAccess %s: %s", _current.name, expr.member_name); |
1233 | + if (expr.inner == null) { |
1234 | + // this is the last iteration |
1235 | + // lookup the name in all the visible symbols |
1236 | if (_current != null) { |
1237 | - DataType d = _current.scope_lookup_datatype_for_variable (CompareMode.EXACT, expr.member_name); |
1238 | + // try the first optimized path |
1239 | + DataType d = _current.lookup_datatype_for_variable_name (CompareMode.EXACT, member_name); |
1240 | if (d != null) { |
1241 | member_name = d.type_name; |
1242 | + } else if (_current.parent != null) { |
1243 | + d = _current.parent.lookup_datatype_for_symbol_name (CompareMode.EXACT, member_name); |
1244 | + if (d != null) { |
1245 | + member_name = d.type_name; |
1246 | + } /* else { |
1247 | + // this is the slowest path |
1248 | + d = _current.scope_lookup_datatype_for_name (CompareMode.EXACT, member_name); |
1249 | + if (d != null) { |
1250 | + member_name = d.type_name; |
1251 | + } |
1252 | + }*/ |
1253 | } |
1254 | } |
1255 | - |
1256 | - // if not found assume that is a static type |
1257 | - if (member_name == null) |
1258 | - member_name = expr.member_name; |
1259 | + } |
1260 | + if (_inferred_type.type_name == null || _inferred_type.type_name == "") { |
1261 | + _inferred_type.type_name = member_name; |
1262 | + } else { |
1263 | _inferred_type.type_name = "%s.%s".printf (member_name, _inferred_type.type_name); |
1264 | } |
1265 | } |
1266 | @@ -777,7 +931,6 @@ |
1267 | |
1268 | public override void visit_binary_expression (BinaryExpression expr) |
1269 | { |
1270 | - //debug ("vidit binary expr %p", expr); |
1271 | expr.accept_children (this); |
1272 | } |
1273 | |
1274 | @@ -788,8 +941,6 @@ |
1275 | |
1276 | if (_inferred_type.type_name == null || _inferred_type.type_name == "") |
1277 | _inferred_type.type_name = "bool"; |
1278 | - else if (_inferred_type.type_name != "bool") |
1279 | - _inferred_type.type_name = "%s.%s".printf ("bool", _inferred_type.type_name); |
1280 | } |
1281 | |
1282 | |
1283 | @@ -800,8 +951,6 @@ |
1284 | |
1285 | if (_inferred_type.type_name == null || _inferred_type.type_name == "") |
1286 | _inferred_type.type_name = "char"; |
1287 | - else if (_inferred_type.type_name != "char") |
1288 | - _inferred_type.type_name = "%s.%s".printf ("char", _inferred_type.type_name); |
1289 | } |
1290 | |
1291 | public override void visit_integer_literal (IntegerLiteral lit) |
1292 | @@ -811,8 +960,6 @@ |
1293 | |
1294 | if (_inferred_type.type_name == null || _inferred_type.type_name == "") |
1295 | _inferred_type.type_name = lit.type_name; |
1296 | - else if (_inferred_type.type_name != lit.type_name) |
1297 | - _inferred_type.type_name = "%s.%s".printf (lit.type_name, _inferred_type.type_name); |
1298 | } |
1299 | |
1300 | public override void visit_real_literal (RealLiteral lit) |
1301 | @@ -821,8 +968,6 @@ |
1302 | return; |
1303 | if (_inferred_type.type_name == null || _inferred_type.type_name == "") |
1304 | _inferred_type.type_name = lit.get_type_name (); |
1305 | - else if (_inferred_type.type_name != lit.get_type_name ()) |
1306 | - _inferred_type.type_name = "%s.%s".printf (lit.get_type_name (), _inferred_type.type_name); |
1307 | } |
1308 | |
1309 | public override void visit_string_literal (StringLiteral lit) |
1310 | @@ -832,8 +977,6 @@ |
1311 | |
1312 | if (_inferred_type.type_name == null || _inferred_type.type_name == "") |
1313 | _inferred_type.type_name = "string"; |
1314 | - else if (_inferred_type.type_name != "string") |
1315 | - _inferred_type.type_name = "%s.%s".printf ("string", _inferred_type.type_name); |
1316 | } |
1317 | |
1318 | public override void visit_declaration_statement (DeclarationStatement stmt) |
1319 | @@ -885,7 +1028,7 @@ |
1320 | { |
1321 | var s = visit_scoped_codenode ("catch", clause, clause.body); |
1322 | var d = new DataType (get_datatype_typename (clause.error_type), clause.variable_name); |
1323 | - s.add_local_variable (d); |
1324 | + s.add_local_variable (d); |
1325 | } |
1326 | |
1327 | public override void visit_if_statement (IfStatement stmt) |
1328 | @@ -965,7 +1108,7 @@ |
1329 | { |
1330 | var prev_vala_fqn = _vala_symbol_fqn; |
1331 | var prev = _current; |
1332 | - var prev_sr = _current_sr; |
1333 | + unowned SourceReference prev_sr = _current_sr; |
1334 | |
1335 | set_fqn ("!%s".printf (name)); |
1336 | int last_line = 0; |
1337 | |
1338 | === modified file 'plugins/completion/afrodite-provider/afrodite/completionengine.vala' |
1339 | --- plugins/completion/afrodite-provider/afrodite/completionengine.vala 2010-12-30 07:38:50 +0000 |
1340 | +++ plugins/completion/afrodite-provider/afrodite/completionengine.vala 2011-03-10 19:26:24 +0000 |
1341 | @@ -37,16 +37,16 @@ |
1342 | |
1343 | private Mutex _source_queue_mutex; |
1344 | private Mutex _merge_queue_mutex; |
1345 | - private Mutex _ast_mutex = null; |
1346 | |
1347 | private unowned Thread<int> _parser_thread; |
1348 | private int _parser_stamp = 0; |
1349 | private int _parser_remaining_files = 0; |
1350 | private int _current_parsing_total_file_count = 0; |
1351 | private bool _glib_init = false; |
1352 | - |
1353 | + private bool _is_parsing = false; |
1354 | + |
1355 | private Ast _ast; |
1356 | - private Vala.HashMap<string, ParseResult> _parse_result_list = new Vala.HashMap<string, ParseResult> (GLib.str_hash, GLib.str_equal, GLib.direct_equal); |
1357 | + private Vala.List<ParseResult> _parse_result_list = new Vala.ArrayList<ParseResult> (); |
1358 | private uint _idle_id = 0; |
1359 | |
1360 | public CompletionEngine (string? id = null) |
1361 | @@ -62,16 +62,13 @@ |
1362 | _merge_queue_mutex = new Mutex (); |
1363 | |
1364 | _ast = new Ast (); |
1365 | - _ast_mutex = new Mutex (); |
1366 | } |
1367 | |
1368 | ~Completion () |
1369 | { |
1370 | Utils.trace ("Completion %s destroy", id); |
1371 | // invalidate the ast so the parser thread will exit asap |
1372 | - _ast_mutex.lock (); |
1373 | _ast = null; |
1374 | - _ast_mutex.unlock (); |
1375 | |
1376 | if (AtomicInt.@get (ref _parser_stamp) != 0) { |
1377 | Utils.trace ("join the parser thread before exit"); |
1378 | @@ -88,7 +85,7 @@ |
1379 | public bool is_parsing |
1380 | { |
1381 | get { |
1382 | - return AtomicInt.@get (ref _parser_stamp) != 0; |
1383 | + return _is_parsing; |
1384 | } |
1385 | } |
1386 | |
1387 | @@ -121,8 +118,10 @@ |
1388 | return null; |
1389 | } |
1390 | |
1391 | - public void queue_sources (Vala.List<SourceItem> sources) |
1392 | + public bool queue_sources (Vala.List<SourceItem> sources, bool no_update_check = false) |
1393 | { |
1394 | + bool result = false; |
1395 | + |
1396 | _source_queue_mutex.@lock (); |
1397 | if (!_glib_init) { |
1398 | // merge standard base vapi (glib and gobject) |
1399 | @@ -144,22 +143,36 @@ |
1400 | } |
1401 | } |
1402 | foreach (SourceItem source in sources) { |
1403 | - var item = source_queue_contains (source); |
1404 | - if (item == null || item.content != source.content) { |
1405 | - /* |
1406 | - if (source.content == null || source.content == "") |
1407 | - Utils.trace ("%s: queued source %s. sources to parse %d", id, source.path, source_queue.size); |
1408 | - else |
1409 | - Utils.trace ("%s: queued live buffer %s. sources to parse %d", id, source.path, source_queue.size); |
1410 | - */ |
1411 | - if (item != null) |
1412 | - _source_queue.remove (item); |
1413 | - |
1414 | - _source_queue.add (source.copy ()); |
1415 | - } |
1416 | - else if (item.content == null && source.content != null) { |
1417 | - item.content = source.content; |
1418 | - //Utils.trace ("%s: updated live buffer %s. sources to parse %d", id, source.path, source_queue.size); |
1419 | + bool skip_unchanged_file = false; |
1420 | + |
1421 | + // test if file is really changed but only if it's not a live buffer |
1422 | + if (no_update_check == false && source.content == null && _ast != null) { |
1423 | + var sf = _ast.lookup_source_file (source.path); |
1424 | + if (sf != null && sf.update_last_modification_time ()) { |
1425 | + Utils.trace ("engine %s: skip unchanged source %s", id, source.path); |
1426 | + skip_unchanged_file = true; |
1427 | + } |
1428 | + } |
1429 | + |
1430 | + if (!skip_unchanged_file) |
1431 | + { |
1432 | + var item = source_queue_contains (source); |
1433 | + if (item == null || item.content != source.content) { |
1434 | + /* |
1435 | + if (source.content == null || source.content == "") |
1436 | + Utils.trace ("%s: queued source %s. sources to parse %d", id, source.path, source_queue.size); |
1437 | + else |
1438 | + Utils.trace ("%s: queued live buffer %s. sources to parse %d", id, source.path, source_queue.size); |
1439 | + */ |
1440 | + if (item != null) |
1441 | + _source_queue.remove (item); |
1442 | + |
1443 | + _source_queue.add (source.copy ()); |
1444 | + } |
1445 | + else if (item.content == null && source.content != null) { |
1446 | + item.content = source.content; |
1447 | + //Utils.trace ("%s: updated live buffer %s. sources to parse %d", id, source.path, source_queue.size); |
1448 | + } |
1449 | } |
1450 | } |
1451 | _source_queue_mutex.@unlock (); |
1452 | @@ -168,7 +181,9 @@ |
1453 | create_parser_thread (); |
1454 | } else { |
1455 | AtomicInt.inc (ref _parser_stamp); |
1456 | - } |
1457 | + } |
1458 | + |
1459 | + return result; |
1460 | } |
1461 | |
1462 | public void queue_sourcefile (string path, string? content = null, bool is_vapi = false, bool is_glib = false) |
1463 | @@ -193,52 +208,12 @@ |
1464 | |
1465 | queue_sources (sources); |
1466 | } |
1467 | - |
1468 | - public bool try_acquire_ast (out Ast ast, int retry_count = -1) |
1469 | - { |
1470 | - bool res = false; |
1471 | - ast = null; |
1472 | - bool first_run = true; |
1473 | - int file_count = 0; |
1474 | - int retry = 0; |
1475 | - |
1476 | - while (ast == null |
1477 | - && _ast_mutex != null |
1478 | - && (first_run || (file_count = AtomicInt.get (ref _current_parsing_total_file_count)) <= 2)) |
1479 | - { |
1480 | - first_run = false; |
1481 | - res = _ast_mutex.@trylock (); |
1482 | - if (res) { |
1483 | - ast = _ast; |
1484 | - } else { |
1485 | - if (retry_count < 0 || retry < retry_count) { |
1486 | - retry++; |
1487 | - GLib.Thread.usleep (100 * 1000); |
1488 | - } else { |
1489 | - break; |
1490 | - } |
1491 | - } |
1492 | - } |
1493 | - |
1494 | -#if DEBUG |
1495 | - if (ast == null) { |
1496 | - //Utils.trace ("can't acquire lock: %d", file_count); |
1497 | - } else { |
1498 | - Utils.trace ("lock acquired: %d", file_count); |
1499 | - } |
1500 | -#endif |
1501 | - |
1502 | - return res; |
1503 | - } |
1504 | - |
1505 | - public void release_ast (Ast ast) |
1506 | - { |
1507 | - if (_ast != ast) { |
1508 | - warning ("%s: release_ast requested for unknown ast instance", id); |
1509 | - return; |
1510 | - } |
1511 | - |
1512 | - _ast_mutex.unlock (); |
1513 | + |
1514 | + public Ast ast |
1515 | + { |
1516 | + get { |
1517 | + return _ast; |
1518 | + } |
1519 | } |
1520 | |
1521 | private void create_parser_thread () |
1522 | @@ -257,26 +232,19 @@ |
1523 | { |
1524 | #if DEBUG |
1525 | GLib.Timer timer = new GLib.Timer (); |
1526 | - double start_parsing_time = 0; |
1527 | - double parsing_time = 0; |
1528 | double start_time = 0; |
1529 | timer.start (); |
1530 | #endif |
1531 | Utils.trace ("engine %s: parser thread *** starting ***...", id); |
1532 | - begin_parsing (this); |
1533 | + |
1534 | Vala.List<SourceItem> sources = new ArrayList<SourceItem> (); |
1535 | |
1536 | while (true) { |
1537 | -#if DEBUG |
1538 | - start_parsing_time = timer.elapsed (); |
1539 | -#endif |
1540 | int stamp = AtomicInt.get (ref _parser_stamp); |
1541 | - // set the number of sources to process + 1, because the last one |
1542 | - // will be decreased by the resolve part |
1543 | - AtomicInt.set (ref _parser_remaining_files, _source_queue.size + 1); |
1544 | + // set the number of sources to process |
1545 | + AtomicInt.set (ref _parser_remaining_files, _source_queue.size ); |
1546 | // get the source to parse |
1547 | _source_queue_mutex.@lock (); |
1548 | - int source_count = _source_queue.size; |
1549 | foreach (SourceItem item in _source_queue) { |
1550 | sources.add (item.copy ()); |
1551 | } |
1552 | @@ -287,109 +255,28 @@ |
1553 | _source_queue.clear (); |
1554 | _source_queue_mutex.@unlock (); |
1555 | |
1556 | - AstMerger merger = null; |
1557 | foreach (SourceItem source in sources) { |
1558 | - bool skip_unchanged_file = false; |
1559 | - |
1560 | - // test if file is really changed but only if it's not a live buffer |
1561 | - if (source.content == null) { |
1562 | - _ast_mutex.@lock (); |
1563 | - if (_ast != null) { |
1564 | - var sf = _ast.lookup_source_file (source.path); |
1565 | - if (sf != null) { |
1566 | - if (sf.update_last_modification_time ()) { |
1567 | - // no need to reparse the source since it isn't changed |
1568 | - Utils.trace ("engine %s: source file parsing optimized out since it isn't changed: %s", id, source.path); |
1569 | - _ast_mutex.@unlock (); |
1570 | - skip_unchanged_file = true; |
1571 | - } |
1572 | - } |
1573 | - } |
1574 | - _ast_mutex.@unlock (); |
1575 | - } |
1576 | - |
1577 | - if (!skip_unchanged_file) { |
1578 | -#if DEBUG |
1579 | - Utils.trace ("engine %s: parsing source: %s", id, source.path); |
1580 | - start_time = timer.elapsed (); |
1581 | -#endif |
1582 | - |
1583 | - Parser p = new Parser.with_source (source); |
1584 | - var parse_results = p.parse (); |
1585 | - lock (_parse_result_list) { |
1586 | - _parse_result_list.set (source.path, parse_results); |
1587 | - if (_idle_id == 0) |
1588 | - _idle_id = Idle.add_full (Priority.LOW, on_parse_results); |
1589 | - } |
1590 | -#if DEBUG |
1591 | - Utils.trace ("engine %s: parsing source: %s done %g", id, source.path, timer.elapsed () - start_time); |
1592 | -#endif |
1593 | - source.context = p.context; |
1594 | - if (source.context == null) |
1595 | - critical ("source %s context == null, non thread safe access to source item", source.path); |
1596 | - else { |
1597 | - foreach (Vala.SourceFile s in source.context.get_source_files ()) { |
1598 | - if (s.filename == source.path) { |
1599 | - // do the real merge |
1600 | - _ast_mutex.@lock (); |
1601 | - if (_ast != null) { |
1602 | - bool source_exists = _ast.lookup_source_file (source.path) != null; |
1603 | - |
1604 | - // if the ast is still valid: not null |
1605 | - // and not |
1606 | - // if I'm parsing just one source and there are errors and the source already exists in the ast: I'll keep the previous copy |
1607 | - // do the merge |
1608 | - if (!(source_count == 1 && source_exists && p.context.report.get_errors () > 0)) { |
1609 | - if (merger == null) { |
1610 | - // lazy init the merger, here I'm sure that _ast != null |
1611 | - merger = new AstMerger (_ast); |
1612 | - } |
1613 | - if (source_exists) { |
1614 | - merger.remove_source_filename (source.path); |
1615 | - } |
1616 | -#if DEBUG |
1617 | - Utils.trace ("engine %s: merging source %s", id, source.path); |
1618 | - start_time = timer.elapsed (); |
1619 | -#endif |
1620 | - merger.merge_vala_context (s, source.context, source.is_glib); |
1621 | -#if DEBUG |
1622 | - Utils.trace ("engine %s: merging source %s done %g", id, source.path, timer.elapsed () - start_time); |
1623 | -#endif |
1624 | - } |
1625 | - } |
1626 | - _ast_mutex.unlock (); |
1627 | - |
1628 | - //timer.stop (); |
1629 | - //debug ("%s: merging context and file %s in %g", id, s.filename, timer.elapsed ()); |
1630 | - break; |
1631 | - } |
1632 | - } |
1633 | - } |
1634 | - } |
1635 | +#if DEBUG |
1636 | + Utils.trace ("engine %s: parsing source: %s", id, source.path); |
1637 | + start_time = timer.elapsed (); |
1638 | +#endif |
1639 | + |
1640 | + Parser p = new Parser.with_source (source); |
1641 | + var parse_results = p.parse (); |
1642 | + lock (_parse_result_list) { |
1643 | + _parse_result_list.add (parse_results); |
1644 | + if (_idle_id == 0) |
1645 | + //_idle_id = Idle.add (this.on_parse_results, Priority.LOW); |
1646 | + _idle_id = Timeout.add (250, this.on_parse_results, Priority.LOW); |
1647 | + } |
1648 | +#if DEBUG |
1649 | + Utils.trace ("engine %s: parsing source: %s done %g", id, source.path, timer.elapsed () - start_time); |
1650 | +#endif |
1651 | AtomicInt.add (ref _parser_remaining_files, -1); |
1652 | } |
1653 | -#if DEBUG |
1654 | - parsing_time += (timer.elapsed () - start_parsing_time); |
1655 | -#endif |
1656 | |
1657 | - _ast_mutex.@lock (); |
1658 | - if (_ast != null) { |
1659 | -#if DEBUG |
1660 | - //_ast.dump_symbols (); |
1661 | - Utils.trace ("engine %s: resolving ast", id); |
1662 | - start_time = timer.elapsed (); |
1663 | -#endif |
1664 | - var resolver = new SymbolResolver (); |
1665 | - resolver.resolve (_ast); |
1666 | -#if DEBUG |
1667 | - Utils.trace ("engine %s: resolving ast done %g", id, timer.elapsed () - start_time); |
1668 | -#endif |
1669 | - } |
1670 | - AtomicInt.add (ref _parser_remaining_files, -1); |
1671 | - _ast_mutex.unlock (); |
1672 | - |
1673 | sources.clear (); |
1674 | - |
1675 | + |
1676 | //check for changes or exit request |
1677 | if (_ast == null || AtomicInt.compare_and_exchange (ref _parser_stamp, stamp, 0)) { |
1678 | break; |
1679 | @@ -402,36 +289,152 @@ |
1680 | |
1681 | #if DEBUG |
1682 | timer.stop (); |
1683 | - Utils.trace ("engine %s: parser thread *** exiting *** (elapsed time parsing %g, resolving %g)...", id, parsing_time, timer.elapsed ()); |
1684 | + Utils.trace ("engine %s: parser thread *** exiting *** (elapsed time parsing %g)...", id, timer.elapsed()); |
1685 | #endif |
1686 | - end_parsing (this); |
1687 | return 0; |
1688 | } |
1689 | - |
1690 | + |
1691 | + private void on_begin_parsing () |
1692 | + { |
1693 | + if (!_is_parsing) { |
1694 | + _is_parsing = true; |
1695 | + begin_parsing (this); |
1696 | + } |
1697 | + } |
1698 | + |
1699 | + private void on_end_parsing () |
1700 | + { |
1701 | + if (AtomicInt.@get (ref _current_parsing_total_file_count) == 0) { |
1702 | + _is_parsing = false; |
1703 | + end_parsing (this); |
1704 | + } |
1705 | + } |
1706 | + |
1707 | + |
1708 | private bool on_parse_results () |
1709 | { |
1710 | - bool more_results = true; |
1711 | - string filename = null; |
1712 | - ParseResult result = null; |
1713 | + bool merge_scheduled = false; |
1714 | |
1715 | lock (_parse_result_list) { |
1716 | if (_parse_result_list.size > 0) { |
1717 | - foreach (string key in _parse_result_list.get_keys ()) { |
1718 | - result = _parse_result_list.get (key); |
1719 | - _parse_result_list.remove (key); |
1720 | - filename = key; |
1721 | - break; // one iteration |
1722 | + foreach (ParseResult key in _parse_result_list) { |
1723 | + if (!merge_scheduled) { |
1724 | + merge_scheduled = true; |
1725 | + merge_and_resolve.begin (key, this.on_merge_and_resolve_ended); |
1726 | + _parse_result_list.remove (key); |
1727 | + break; |
1728 | + } |
1729 | } |
1730 | - } |
1731 | - if (_parse_result_list.size == 0) { |
1732 | + } else { |
1733 | + // Tell to the parser thread the a new Idle should be created |
1734 | + // for the merge process |
1735 | _idle_id = 0; |
1736 | - more_results = false; |
1737 | - } |
1738 | - } |
1739 | - if (result != null) { |
1740 | - this.file_parsed (this, filename, result); |
1741 | - } |
1742 | - return more_results; |
1743 | + } |
1744 | + } |
1745 | + |
1746 | + if (merge_scheduled) { |
1747 | + on_begin_parsing(); |
1748 | + } else { |
1749 | + // this is the last run after the merge |
1750 | + on_end_parsing (); |
1751 | + } |
1752 | + |
1753 | + return false; |
1754 | + } |
1755 | + |
1756 | + private void on_merge_and_resolve_ended (GLib.Object? source, GLib.AsyncResult r) |
1757 | + { |
1758 | + merge_and_resolve.end (r); |
1759 | + //_idle_id = Idle.add (this.on_parse_results, Priority.LOW); |
1760 | + _idle_id = Timeout.add (250, this.on_parse_results, Priority.LOW); |
1761 | + } |
1762 | + |
1763 | + private async ParseResult merge_and_resolve (ParseResult result) |
1764 | + { |
1765 | + Utils.trace ("engine %s: async merge and resolve: %s", id, result.source_path); |
1766 | + foreach (Vala.SourceFile s in result.context.get_source_files ()) { |
1767 | + if (s.filename == result.source_path) { |
1768 | + var ast_source = _ast.lookup_source_file (result.source_path); |
1769 | + bool source_exists = ast_source != null; |
1770 | + bool need_update = true; |
1771 | + |
1772 | + // if I already parsed this source and this copy is a live gedit buffer |
1773 | + // and the parsing contains some error, I maintain the previous copy in the ast |
1774 | + if (!(source_exists && result.is_edited && result.errors.size > 0)) |
1775 | + { |
1776 | + // if the source was already parsed and it's not opend in a edit window |
1777 | + if (source_exists && !result.is_edited) { |
1778 | + need_update = ast_source.update_last_modification_time(); |
1779 | + } |
1780 | + // this is important! |
1781 | + // TODO: we shouldn't hold this reference lookup_source_file should return an unowned ref |
1782 | + ast_source = null; |
1783 | + if (need_update) { |
1784 | + yield perform_merge_and_resolve (s, result, source_exists); |
1785 | + this.file_parsed (this, result.source_path, result); |
1786 | + } |
1787 | + } else { |
1788 | + Utils.trace ("engine %s: source (live buffer) with errors mantaining the previous parsing: %s", id, result.source_path); |
1789 | + } |
1790 | + break; // found the file |
1791 | + } |
1792 | + } |
1793 | + |
1794 | + return result; |
1795 | + } |
1796 | + |
1797 | + private async void perform_merge_and_resolve (Vala.SourceFile s, ParseResult result, bool source_exists) |
1798 | + { |
1799 | + yield merge_vala_source (s, result, source_exists); |
1800 | + yield resolve_ast (); |
1801 | + } |
1802 | + |
1803 | + private async void merge_vala_source (Vala.SourceFile s, ParseResult result, bool source_exists) |
1804 | + { |
1805 | +#if DEBUG |
1806 | + GLib.Timer timer = new GLib.Timer (); |
1807 | + double start_time = 0, elapsed; |
1808 | + timer.start (); |
1809 | +#endif |
1810 | + var merger = new AstMerger (_ast); |
1811 | + if (source_exists) { |
1812 | +#if DEBUG |
1813 | + Utils.trace ("engine %s: removing source (%p) %s", id, result, result.source_path); |
1814 | + start_time = timer.elapsed (); |
1815 | +#endif |
1816 | + yield merger.remove_source_filename (result.source_path); |
1817 | +#if DEBUG |
1818 | + Utils.trace ("engine %s: removing source (%p) %s done %g", id, result, result.source_path, timer.elapsed () - start_time); |
1819 | +#endif |
1820 | + } |
1821 | +#if DEBUG |
1822 | + Utils.trace ("engine %s: merging source %s", id, result.source_path); |
1823 | + start_time = timer.elapsed (); |
1824 | +#endif |
1825 | + yield merger.merge_vala_context (s, result.context, result.is_glib); |
1826 | + result.context = null; // let's free some memory |
1827 | + merger = null; |
1828 | +#if DEBUG |
1829 | + elapsed = timer.elapsed () - start_time; |
1830 | + Utils.trace ("engine %s: merging source %s done %g %s", id, result.source_path, elapsed, elapsed > 0.7 ? " <== Warning" : ""); |
1831 | +#endif |
1832 | + } |
1833 | + |
1834 | + private async void resolve_ast () |
1835 | + { |
1836 | +#if DEBUG |
1837 | + GLib.Timer timer = new GLib.Timer (); |
1838 | + double start_time = 0; |
1839 | + timer.start (); |
1840 | + //_ast.dump_symbols (); |
1841 | + Utils.trace ("engine %s: resolving ast", id); |
1842 | + start_time = timer.elapsed (); |
1843 | +#endif |
1844 | + var resolver = new SymbolResolver (); |
1845 | + resolver.resolve (_ast); |
1846 | +#if DEBUG |
1847 | + Utils.trace ("engine %s: resolving ast done %g", id, timer.elapsed () - start_time); |
1848 | +#endif |
1849 | } |
1850 | } |
1851 | } |
1852 | |
1853 | === modified file 'plugins/completion/afrodite-provider/afrodite/parser.vala' |
1854 | --- plugins/completion/afrodite-provider/afrodite/parser.vala 2010-10-14 16:01:50 +0000 |
1855 | +++ plugins/completion/afrodite-provider/afrodite/parser.vala 2011-03-10 19:26:24 +0000 |
1856 | @@ -26,21 +26,15 @@ |
1857 | { |
1858 | public class Parser : GLib.Object |
1859 | { |
1860 | - public CodeContext context = null; |
1861 | - |
1862 | - public Parser (Vala.List<SourceItem> sources) |
1863 | - { |
1864 | - context = new Vala.CodeContext(); |
1865 | - foreach (SourceItem source in sources) { |
1866 | - add_source_item (source); |
1867 | - } |
1868 | - |
1869 | - } |
1870 | - |
1871 | + private CodeContext context = null; |
1872 | + |
1873 | + private unowned SourceItem _source; |
1874 | + |
1875 | public Parser.with_source (SourceItem source_item) |
1876 | { |
1877 | context = new Vala.CodeContext(); |
1878 | add_source_item (source_item); |
1879 | + _source = source_item; |
1880 | } |
1881 | |
1882 | private void add_source_item (SourceItem source) |
1883 | @@ -99,6 +93,11 @@ |
1884 | parser.parse (context); |
1885 | |
1886 | CodeContext.pop (); |
1887 | + |
1888 | + parse_result.source_path = _source.path; |
1889 | + parse_result.is_glib = _source.is_glib; |
1890 | + parse_result.is_edited = _source.content != null; |
1891 | + parse_result.context = context; |
1892 | return parse_result; |
1893 | } |
1894 | } |
1895 | |
1896 | === modified file 'plugins/completion/afrodite-provider/afrodite/parseresult.vala' |
1897 | --- plugins/completion/afrodite-provider/afrodite/parseresult.vala 2010-10-14 16:01:50 +0000 |
1898 | +++ plugins/completion/afrodite-provider/afrodite/parseresult.vala 2011-03-10 19:26:24 +0000 |
1899 | @@ -30,6 +30,11 @@ |
1900 | public Vala.List<string> errors = new Vala.ArrayList<string> (); |
1901 | public Vala.List<string> notes = new Vala.ArrayList<string> (); |
1902 | |
1903 | + public string source_path = null; |
1904 | + public bool is_glib = false; |
1905 | + public Vala.CodeContext context = null; |
1906 | + public bool is_edited = false; |
1907 | + |
1908 | public override void warn (Vala.SourceReference? source, string message) |
1909 | { |
1910 | base.warn (source, message); |
1911 | |
1912 | === modified file 'plugins/completion/afrodite-provider/afrodite/sourcefile.vala' |
1913 | --- plugins/completion/afrodite-provider/afrodite/sourcefile.vala 2010-10-14 16:01:50 +0000 |
1914 | +++ plugins/completion/afrodite-provider/afrodite/sourcefile.vala 2011-03-10 19:26:24 +0000 |
1915 | @@ -69,16 +69,10 @@ |
1916 | ~SourceFile () |
1917 | { |
1918 | Utils.trace ("SourceFile destroying: %s", filename); |
1919 | -#if DEBUG |
1920 | - Utils.trace (" symbol count before destroy %d", parent.leaked_symbols.size); |
1921 | -#endif |
1922 | while (symbols != null && symbols.size > 0) { |
1923 | var symbol = symbols.get (0); |
1924 | remove_symbol (symbol); |
1925 | } |
1926 | -#if DEBUG |
1927 | - Utils.trace (" symbol count after destroy %d", parent.leaked_symbols.size); |
1928 | -#endif |
1929 | Utils.trace ("SourceFile destroyed: %s", filename); |
1930 | } |
1931 | |
1932 | @@ -130,21 +124,11 @@ |
1933 | if (symbols == null) { |
1934 | symbols = new ArrayList<unowned Symbol> (); |
1935 | } |
1936 | - assert (symbols.contains (symbol) == false); |
1937 | |
1938 | symbols.add (symbol); |
1939 | |
1940 | - |
1941 | parent.symbols.set (symbol.fully_qualified_name, symbol); |
1942 | -#if DEBUG |
1943 | - // debug |
1944 | - if (!parent.leaked_symbols.contains (symbol)) { |
1945 | - //parent.leaked_symbols.add (symbol); |
1946 | - symbol.weak_ref (this.on_symbol_destroy); |
1947 | - } else { |
1948 | - Utils.trace ("Symbol already added to the leak check: %s", symbol.fully_qualified_name); |
1949 | - } |
1950 | -#endif |
1951 | + parent.unresolved_symbols.add(symbol); |
1952 | } |
1953 | |
1954 | public void remove_symbol (Symbol symbol) |
1955 | @@ -157,6 +141,7 @@ |
1956 | |
1957 | if (!symbol.has_source_references) { |
1958 | parent.symbols.remove (symbol.fully_qualified_name); |
1959 | + parent.unresolved_symbols.remove (symbol); |
1960 | if (symbol.parent != null) { |
1961 | if (symbol.is_generic_type_argument) { |
1962 | symbol.parent.remove_generic_type_argument (symbol); |
1963 | @@ -177,13 +162,5 @@ |
1964 | return symbols != null; |
1965 | } |
1966 | } |
1967 | - |
1968 | -#if DEBUG |
1969 | - private void on_symbol_destroy (Object obj) |
1970 | - { |
1971 | - parent.leaked_symbols.remove ((Symbol)obj); |
1972 | - //Utils.trace ("symbol destroyed (%p)", obj); |
1973 | - } |
1974 | -#endif |
1975 | } |
1976 | } |
1977 | |
1978 | === modified file 'plugins/completion/afrodite-provider/afrodite/sourcereference.vala' |
1979 | --- plugins/completion/afrodite-provider/afrodite/sourcereference.vala 2010-10-14 16:01:50 +0000 |
1980 | +++ plugins/completion/afrodite-provider/afrodite/sourcereference.vala 2011-03-10 19:26:24 +0000 |
1981 | @@ -23,13 +23,13 @@ |
1982 | |
1983 | namespace Afrodite |
1984 | { |
1985 | - public class SourceReference : Object |
1986 | + public class SourceReference |
1987 | { |
1988 | - public unowned SourceFile file { get; set; } |
1989 | - public int first_line { get; set; } |
1990 | - public int last_line { get; set; } |
1991 | - public int first_column { get; set; } |
1992 | - public int last_column { get; set; } |
1993 | + public unowned SourceFile file; |
1994 | + public int first_line; |
1995 | + public int last_line; |
1996 | + public int first_column; |
1997 | + public int last_column; |
1998 | |
1999 | public bool contains_position (int line, int column) |
2000 | { |
2001 | |
2002 | === modified file 'plugins/completion/afrodite-provider/afrodite/symbol.vala' |
2003 | --- plugins/completion/afrodite-provider/afrodite/symbol.vala 2010-10-14 16:01:50 +0000 |
2004 | +++ plugins/completion/afrodite-provider/afrodite/symbol.vala 2011-03-10 19:26:24 +0000 |
2005 | @@ -24,7 +24,7 @@ |
2006 | |
2007 | namespace Afrodite |
2008 | { |
2009 | - public class Symbol : Object |
2010 | + public class Symbol |
2011 | { |
2012 | public static VoidType VOID = new VoidType (); |
2013 | public static EllipsisType ELLIPSIS = new EllipsisType (); |
2014 | @@ -346,7 +346,7 @@ |
2015 | return null; |
2016 | } |
2017 | |
2018 | - public DataType? lookup_datatype_for_variable (CompareMode mode, string name, SymbolAccessibility access = SymbolAccessibility.ANY) |
2019 | + public DataType? lookup_datatype_for_variable_name (CompareMode mode, string name, SymbolAccessibility access = SymbolAccessibility.ANY) |
2020 | { |
2021 | if (has_local_variables) { |
2022 | foreach (DataType d in local_variables) { |
2023 | @@ -355,7 +355,7 @@ |
2024 | } |
2025 | } |
2026 | } |
2027 | - |
2028 | + |
2029 | // search in symbol parameters |
2030 | if (has_parameters) { |
2031 | foreach (DataType type in parameters) { |
2032 | @@ -365,6 +365,11 @@ |
2033 | } |
2034 | } |
2035 | |
2036 | + return null; |
2037 | + } |
2038 | + |
2039 | + public DataType? lookup_datatype_for_symbol_name (CompareMode mode, string name, SymbolAccessibility access = SymbolAccessibility.ANY) |
2040 | + { |
2041 | if (has_children) { |
2042 | foreach (Symbol s in this.children) { |
2043 | if ((s.access & access) != 0 |
2044 | @@ -377,7 +382,7 @@ |
2045 | if (has_base_types) { |
2046 | foreach (DataType d in this.base_types) { |
2047 | if (d.symbol != null) { |
2048 | - var r = d.symbol.lookup_datatype_for_variable (mode, name, |
2049 | + var r = d.symbol.lookup_datatype_for_symbol_name (mode, name, |
2050 | SymbolAccessibility.INTERNAL | SymbolAccessibility.PROTECTED | SymbolAccessibility.PROTECTED); |
2051 | if (r != null) { |
2052 | return d; |
2053 | @@ -387,15 +392,24 @@ |
2054 | } |
2055 | return null; |
2056 | } |
2057 | + |
2058 | + public DataType? lookup_datatype_for_name (CompareMode mode, string name, SymbolAccessibility access = SymbolAccessibility.ANY) |
2059 | + { |
2060 | + var result = lookup_datatype_for_variable_name (mode, name, access); |
2061 | + if (result != null) |
2062 | + return result; |
2063 | + |
2064 | + return lookup_datatype_for_symbol_name (mode, name, access); |
2065 | + } |
2066 | |
2067 | - public DataType? scope_lookup_datatype_for_variable (CompareMode mode, string name) |
2068 | + public DataType? scope_lookup_datatype_for_name (CompareMode mode, string name) |
2069 | { |
2070 | - DataType result = lookup_datatype_for_variable (mode, name); |
2071 | + DataType result = lookup_datatype_for_name (mode, name); |
2072 | |
2073 | if (result == null) { |
2074 | |
2075 | if (this.parent != null) { |
2076 | - result = this.parent.scope_lookup_datatype_for_variable (mode, name); |
2077 | + result = this.parent.scope_lookup_datatype_for_name (mode, name); |
2078 | } |
2079 | |
2080 | if (result == null) { |
2081 | @@ -405,7 +419,7 @@ |
2082 | if (s.file.has_using_directives) { |
2083 | foreach (var u in s.file.using_directives) { |
2084 | if (!u.unresolved) { |
2085 | - result = u.symbol.lookup_datatype_for_variable (mode, name, SymbolAccessibility.INTERNAL | SymbolAccessibility.PUBLIC); |
2086 | + result = u.symbol.lookup_datatype_for_symbol_name (mode, name, SymbolAccessibility.INTERNAL | SymbolAccessibility.PUBLIC); |
2087 | if (result != null) { |
2088 | break; |
2089 | } |
2090 | @@ -522,7 +536,6 @@ |
2091 | generic_type_arguments = new ArrayList<Symbol> (); |
2092 | } |
2093 | |
2094 | - assert (generic_type_arguments.contains(sym) == false); |
2095 | //debug ("added generic %s to %s", sym.name, this.fully_qualified_name); |
2096 | //Utils.trace ("add generic type args symbol %s: %s", _fully_qualified_name, sym.fully_qualified_name); |
2097 | generic_type_arguments.add (sym); |
2098 | @@ -623,16 +636,18 @@ |
2099 | } |
2100 | } |
2101 | |
2102 | - public SourceReference? lookup_source_reference_filename (string filename) |
2103 | + public unowned SourceReference? lookup_source_reference_filename (string filename) |
2104 | { |
2105 | + unowned SourceReference? result = null; |
2106 | if (has_source_references) { |
2107 | foreach (SourceReference reference in source_references) { |
2108 | if (reference.file.filename == filename) |
2109 | - return reference; |
2110 | + result = reference; |
2111 | + break; |
2112 | } |
2113 | } |
2114 | |
2115 | - return null; |
2116 | + return result; |
2117 | } |
2118 | |
2119 | public SourceReference? lookup_source_reference_sourcefile (SourceFile source) |
2120 | @@ -1053,7 +1068,6 @@ |
2121 | if (_specialized_symbols == null) |
2122 | _specialized_symbols = new Vala.ArrayList<Symbol> (); |
2123 | |
2124 | - assert (_specialized_symbols.contains (item) == false); |
2125 | _specialized_symbols.add (item); |
2126 | item.generic_parent = this; |
2127 | } |
2128 | @@ -1061,7 +1075,6 @@ |
2129 | public void remove_specialized_symbol (Symbol? item) |
2130 | { |
2131 | assert (item != this); |
2132 | - assert (_specialized_symbols.contains (item)); |
2133 | |
2134 | _specialized_symbols.remove (item); |
2135 | if (item.generic_parent == this) |
2136 | |
2137 | === modified file 'plugins/completion/afrodite-provider/afrodite/symbolresolver.vala' |
2138 | --- plugins/completion/afrodite-provider/afrodite/symbolresolver.vala 2010-10-14 16:01:50 +0000 |
2139 | +++ plugins/completion/afrodite-provider/afrodite/symbolresolver.vala 2011-03-10 19:26:24 +0000 |
2140 | @@ -44,13 +44,12 @@ |
2141 | |
2142 | // first resolve the using directives |
2143 | if (_ast.has_source_files) { |
2144 | - Symbol dummy; |
2145 | foreach (SourceFile file in _ast.source_files) { |
2146 | if (file.has_using_directives) { |
2147 | foreach (DataType using_directive in file.using_directives) { |
2148 | // |
2149 | if (using_directive.unresolved) { |
2150 | - using_directive.symbol = _ast.lookup (using_directive.type_name, out dummy); |
2151 | + using_directive.symbol = _ast.lookup (using_directive.type_name); |
2152 | if (using_directive.unresolved) |
2153 | message ("file %s - can't resolve using directive: %s", file.filename, using_directive.type_name); |
2154 | } |
2155 | @@ -59,8 +58,12 @@ |
2156 | } |
2157 | } |
2158 | |
2159 | - if (ast.root.has_children) |
2160 | - visit_symbols (ast.root.children); |
2161 | + if (ast.unresolved_symbols.size > 0) { |
2162 | + Afrodite.Utils.trace ("(symbol resolver): symbols to resolve %d", ast.unresolved_symbols.size); |
2163 | + visit_symbols (ast.unresolved_symbols); |
2164 | + Afrodite.Utils.trace ("(symbol resolver): unresolved symbol after resolve process %d", ast.unresolved_symbols.size); |
2165 | + } |
2166 | + |
2167 | } |
2168 | |
2169 | private Symbol? resolve_type (Symbol symbol, DataType type) |
2170 | @@ -303,7 +306,52 @@ |
2171 | |
2172 | } |
2173 | } |
2174 | - |
2175 | + |
2176 | + private bool visit_symbol (Symbol symbol) |
2177 | + { |
2178 | + //print_symbol (symbol); |
2179 | + bool resolved = true; |
2180 | + |
2181 | + // resolving base types |
2182 | + if (symbol.has_base_types) { |
2183 | + foreach (DataType type in symbol.base_types) { |
2184 | + if (type.unresolved) { |
2185 | + type.symbol = resolve_type (symbol, type); |
2186 | + resolved &= !type.unresolved; |
2187 | + } |
2188 | + } |
2189 | + } |
2190 | + // resolving return type |
2191 | + if (symbol.return_type != null) { |
2192 | + if (symbol.return_type.unresolved) { |
2193 | + symbol.return_type.symbol = resolve_type (symbol, symbol.return_type); |
2194 | + resolved &= !symbol.return_type.unresolved; |
2195 | + } |
2196 | + } |
2197 | + |
2198 | + // resolving symbol parameters |
2199 | + if (symbol.has_parameters) { |
2200 | + foreach (DataType type in symbol.parameters) { |
2201 | + if (type.unresolved) { |
2202 | + type.symbol = resolve_type (symbol, type); |
2203 | + resolved &= !type.unresolved; |
2204 | + } |
2205 | + } |
2206 | + } |
2207 | + // resolving local variables |
2208 | + if (symbol.has_local_variables) { |
2209 | + foreach (DataType type in symbol.local_variables) { |
2210 | + if (type.unresolved) { |
2211 | + resolve_symbol (symbol, type); |
2212 | + resolved &= !type.unresolved; |
2213 | + } |
2214 | + } |
2215 | + } |
2216 | + |
2217 | + return resolved; |
2218 | + } |
2219 | + |
2220 | + /* |
2221 | private void visit_symbol (Symbol symbol) |
2222 | { |
2223 | //print_symbol (symbol); |
2224 | @@ -342,13 +390,20 @@ |
2225 | if (symbol.has_children) { |
2226 | visit_symbols (symbol.children); |
2227 | } |
2228 | - } |
2229 | + }*/ |
2230 | |
2231 | - private void visit_symbols (Vala.List<Afrodite.Symbol> symbols) |
2232 | + private void visit_symbols (Vala.List<unowned Afrodite.Symbol> symbols) |
2233 | { |
2234 | + Vala.List<unowned Afrodite.Symbol> resolved = new Vala.ArrayList<unowned Afrodite.Symbol>(); |
2235 | + |
2236 | foreach (Symbol symbol in symbols) { |
2237 | - visit_symbol (symbol); |
2238 | + if (visit_symbol (symbol)) { |
2239 | + resolved.add (symbol); |
2240 | + } |
2241 | } |
2242 | + |
2243 | + foreach (Symbol symbol in resolved) |
2244 | + symbols.remove(symbol); |
2245 | } |
2246 | } |
2247 | } |
Check this a lot because Afrodite could crash but I cannot reproduce it.
Thanks in advance.