Merge lp:~monkey-libre/valide/update-afrodite into lp:valide

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
Reviewer Review Type Date Requested Status
Val(a)IDE Team Pending
Review via email: mp+52905@code.launchpad.net

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 :

Check this a lot because Afrodite could crash but I cannot reproduce it.

Thanks in advance.

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 }

Subscribers

People subscribed via source and target branches

to all changes: