Fix #7202 - update debian release
[roojspacker] / roojspacker / Walker.vala
1 // this walks through the code, and tries to find patterns that match documentable elements..
2
3
4 namespace JSDOC {
5
6         enum WalkerMode {
7                 BUILDING_SYMBOL_TREE,
8                 XXX
9         }
10         
11         public class Walker  : Object
12         {
13                 TokenStream ts;
14                 Gee.ArrayList<string> warnings;
15                 Gee.ArrayList<Scope> scopes;
16                 Gee.HashMap<int,Scope> indexedScopes;
17                 Gee.HashMap<string,Symbol> symbols;
18                 Gee.HashMap<string,string> aliases;
19                 Scope globalScope;
20                 
21         bool global = false;
22         WalkerMode mode =  WalkerMode.XXX; //"BUILDING_SYMBOL_TREE",
23         int braceNesting = 0;
24         
25         DocComment? currentDoc =  null;
26
27         bool munge =  true;
28                 
29                 public Walker(TokenStream ts)
30                 {
31                         this.ts  = ts;
32                         this.warnings= new Gee.ArrayList<string>();
33                         this.scopes = new Gee.ArrayList<Scope>();
34                         this.indexedScopes = new Gee.HashMap<int,Scope>();
35                         this.symbols = new Gee.HashMap<string,Symbol>();
36                         this.aliases = new Gee.HashMap<string,string>();
37                         this.braceNesting = 0;
38                 }
39
40         //warn: function(s) {
41             //this.warnings.push(s);
42         //    print("WARNING:" + htmlescape(s) + "<BR>");
43         //},
44         // defaults should not be initialized here =- otherwise they get duped on new, rather than initalized..
45
46
47
48
49
50
51         public void buildSymbolTree()
52         {
53             //print("<PRE>");
54             
55             this.ts.rewind();
56             this.braceNesting = 0;
57             this.scopes = new Gee.ArrayList<Scope>();;
58                         this.aliases = new Gee.HashMap<string,string>();
59              
60             this.globalScope = new Scope(-1, null, -1,  "$global$", null);
61             this.indexedScopes = new Gee.HashMap<int,Scope>();
62             this.indexedScopes.set(  0,  this.globalScope );
63             
64             this.mode = WalkerMode.BUILDING_SYMBOL_TREE;
65             this.parseScope(this.globalScope,this.emptyAlias());
66             
67         }
68         Gee.HashMap<string,string>  emptyAlias()
69         {
70                 return new Gee.HashMap<string,string> ();
71         }
72         
73         
74
75         string fixAlias (Gee.HashMap<string,string>aliases, string str, bool nomore = false)
76         {
77             var ar = str.split(".");
78             var m = ar[0];
79             
80             //print(str +"?=" +aliases.toSource());
81             if (!aliases.has_key(m)) {
82                 return str;
83             }
84             ar[0] = aliases.get(m);
85             
86             var ret = string.joinv(".", ar);
87             if (nomore != true) {
88                 ret = this.fixAlias(aliases, ret, true);
89             }
90             
91             
92             return ret;
93         }
94
95         
96
97         void parseScope (Scope in_scope, Gee.HashMap<string,string> ealiases) // parse a token stream..
98         {
99             //this.timerPrint("parseScope EnterScope"); 
100             
101             var scope = in_scope;
102             
103             var aliases = new Gee.HashMap<string,string>();
104
105             foreach(var i in ealiases.keys) {
106                 aliases.set(i, ealiases.get(i));
107             }
108                 
109             //print("STARTING SCOPE WITH: " + ealiases.toSource());
110              
111             var expressionBraceNesting = this.braceNesting;
112             var bracketNesting = 0;
113             var parensNesting = 0;
114            
115             
116             var l1 = "", l2 = "";
117             var scopeName = "";
118             
119             
120             var locBraceNest = 0;
121             // determines if we are in object literals...
122             
123             var isObjectLitAr = new Gee.ArrayList<bool>();
124             isObjectLitAr.add(false);
125             //print("SCOPE: ------------------START ----------------");
126
127             this.scopesIn(scope);
128             var scopeLen = this.scopes.size;
129             
130             if (this.ts.cursor < 1) {
131               // this.ts.cursor--; // hopeflly this kludge will work
132             }
133             
134             
135             //print(JSON.stringify(this.ts, null, 4)); Seed.quit();
136             Token token;
137             while (null != ( token = this.ts.next())) {
138                  //GLib.debug("TOK %s", token.asString());
139                 //  this.timerPrint("parseScope AFTER lookT: " + token.toString()); 
140                   
141                 if (token.isType(TokenType.COMM)) {
142                       
143                  
144                     if (!token.isName(TokenName.JSDOC)) {
145                         //print("Walker2 : spce is not JSDOC");
146                         continue; //skip.
147                     }
148                     if (this.currentDoc != null) {
149                         // add it to the current scope????
150                         
151                         this.addSymbol("", true);
152                         GLib.debug("Call addSymbol EMPTY");
153                         //print ( "Unconsumed Doc: " + token.toString())
154                         //throw "Unconsumed Doc (TOKwhitespace): " + this.currentDoc.toSource();
155                     }
156                     
157                    // print ( "NEW COMMENT: " + token.toString())
158                     var newDoc = new DocComment(token.data);
159                     
160                     // it"s a scope changer..
161                     
162                     if (newDoc.getTag(DocTagTitle.SCOPE).size > 0) {
163                         //print("Walker2 : doctag changes scope");
164                         //throw "done";
165                         scope.ident = "$private$|" + newDoc.getTag(DocTagTitle.SCOPE).get(0).desc;
166                         continue;
167                     } 
168                     
169                     // it"s a scope changer..
170                     if (newDoc.getTag(DocTagTitle.SCOPEALIAS).size > 0) {
171                         //print(newDoc.getTag("scopeAlias").toSource());
172                         // @scopeAlias a=b
173                         //print("Walker2 : doctag changes scope (alias)");
174                         var sal = newDoc.getTag(DocTagTitle.SCOPEALIAS).get(0).desc.split("=");
175                         aliases[sal[0].strip()] = sal[1].strip();
176                         
177                         continue;
178                     }
179                     
180                     
181                     /// got a  doc comment..
182                     //token.data might be this.??? (not sure though)
183                     //print("Walker2 : setting currentDoc");
184                     this.currentDoc = newDoc;
185                     continue;
186                 }
187                 
188                 // catch the various issues .. - scoe changes or doc actions..
189                 
190               
191                 
192                 // things that stop comments carrying on...??
193                 
194                 if (this.currentDoc != null && (
195                         token.data == ";" || 
196                         token.data == "}")) {
197
198                     GLib.debug("Call addSymbol EMPTY");                        
199                     this.addSymbol("", true);
200                     
201                     //throw "Unconsumed Doc ("+ token.toString() +"): " + this.currentDoc.toSource();
202                 }
203                     
204                 
205                 // the rest are scoping issues...
206                 
207                 // var a = b;
208                 
209                  if (token.isName(TokenName.VAR) &&
210                  
211                         this.ts.lookTok(1).isType(TokenType.NAME) &&
212                         this.ts.lookTok(2).data == "=" &&
213                         this.ts.lookTok(3).isType(TokenType.NAME) &&
214                         this.ts.lookTok(4).data == ";"  
215                         
216                  
217                  ) {
218                     //print("SET ALIAS:" + this.ts.lookTok(1).data +"=" + this.ts.lookTok(3).data);
219                      
220                     aliases.set(this.ts.lookTok(1).data, this.ts.lookTok(3).data);
221                 
222                 }
223                 
224                 if ((token.data == "eval") || /\.eval$/.match(token.data)) {
225                     this.currentDoc = null;
226                     continue;
227                 }
228               
229                 // extends scoping  *** not sure if the can be x = Roo.apply(....)
230                 // xxx.extends(a,b, {
231                     // $this$=b|b.prototype
232                 // xxx.apply(a, {
233                     // a  << scope
234                 // xxx.applyIf(a, {
235                     // a  << scope
236                 if (token.isType(TokenType.NAME) ) {
237                     
238                     //print("TOK(ident)"+ token.toString());
239                      
240                     if (/\.extend$/.match(token.data) &&
241                         this.ts.lookTok(1).data == "(" &&
242                         this.ts.lookTok(2).isType(TokenType.NAME)  &&
243                         this.ts.lookTok(3).data == "," &&
244                         this.ts.lookTok(4).isType(TokenType.NAME)  &&
245                         this.ts.lookTok(5).data == "," &&
246                         this.ts.lookTok(6).data == "{" 
247                            
248                         ) {
249                         // ignore test for ( a and ,
250                         this.ts.nextTok(); /// (
251                         token = this.ts.nextTok(); // a
252                         scopeName = token.data;
253                         
254                         if (this.currentDoc != null) {
255                                 GLib.debug("Call addSymbol %s", scopeName);
256                             this.addSymbol(scopeName,false,"OBJECT");
257
258                         }
259                         this.ts.nextTok(); // ,
260                         this.ts.nextTok(); // b
261                         
262                         
263                         this.ts.nextTok(); // ,
264                         token = this.ts.nextTok(); // {
265                             
266                         scopeName = this.fixAlias(aliases, scopeName);
267                         
268                         var fnScope = new Scope(this.braceNesting, scope, token.id, // was token.n?
269                                         "$this$=" + scopeName  + "|"+scopeName+".prototype", null
270                                         );
271                         
272     
273                         this.indexedScopes.set(this.ts.cursor, fnScope);
274                         scope = fnScope;
275                         this.scopesIn(fnScope);
276                        
277                         locBraceNest++;
278                         //print(">>" +locBraceNest);
279                         continue; // no more processing..
280                         
281                     }
282                     
283                     // a = Roo.extend(parentname, {
284                         
285                      if (/\.extend$/.match(token.data) &&
286                         this.ts.lookTok(-2).isType(TokenType.NAME)  &&
287                         this.ts.lookTok(-1).data == "=" &&
288                         this.ts.lookTok(1).data == "(" &&
289                         this.ts.lookTok(2).isType(TokenType.NAME) &&
290                         this.ts.lookTok(3).data == "," &&
291                         this.ts.lookTok(4).data == "{" 
292                         ) {
293                         // ignore test for ( a and ,
294                         token = this.ts.lookTok(-2);
295                         scopeName = token.data;
296                         if (this.currentDoc != null) {
297                                 GLib.debug("Call addSymbol %s", scopeName);
298                             this.addSymbol(scopeName,false,"OBJECT");
299
300                         }
301                         this.ts.nextTok(); /// (
302                         this.ts.nextTok(); // parent
303                         
304                         this.ts.nextTok(); // ,
305                         token =  this.ts.nextTok(); // {
306                              
307                         
308                         scopeName = this.fixAlias(aliases,scopeName);
309                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
310                                          "$this$=" + scopeName  + "|"+scopeName+".prototype",
311                                                  null
312                                         );
313                         
314                          
315                         this.indexedScopes.set(this.ts.cursor, fnScope);
316                         scope = fnScope;
317                         this.scopesIn(fnScope);
318                        
319                         locBraceNest++;
320                         //print(">>" +locBraceNest);
321                         continue; // no more processing..
322                         
323                     }
324                     
325                     
326                      // apply ( XXXX,  {
327                     /*
328                     print(JSON.stringify([
329                         token.data,
330                         this.ts.lookTok(1).data ,
331                         this.ts.lookTok(2).type ,
332                         this.ts.lookTok(3).data ,
333                         this.ts.lookTok(4).data 
334                     ], null, 4));
335                     */
336                     
337                     if (/\.(applyIf|apply)$/.match(token.data) && 
338                         this.ts.lookTok(1).data == "("  &&
339                         this.ts.lookTok(2).isType(TokenType.NAME) &&
340                         this.ts.lookTok(3).data == ","  &&
341                         this.ts.lookTok(4).data == "{" 
342                         
343                         ) {
344                         this.ts.nextTok(); /// (
345                          
346                         //print("GOT : applyIF!"); 
347                          
348                         token = this.ts.nextTok(); // b
349                         scopeName = token.data;
350                         
351                                       
352                         if (this.currentDoc != null) {
353                                 GLib.debug("Call addSymbol %s", scopeName);
354                             this.addSymbol(scopeName,false,"OBJECT");
355                         }
356                      
357
358                         
359                         this.ts.nextTok(); /// ,
360                         this.ts.nextTok(); // {
361                         scopeName = this.fixAlias(aliases,scopeName);
362                         var fnScope =   new Scope(this.braceNesting, scope, token.id, // was token.n?
363                                         scopeName, null
364                                         );
365
366                         this.indexedScopes.set(this.ts.cursor, fnScope);
367                         scope = fnScope;
368                         this.scopesIn(fnScope);
369                          
370                         locBraceNest++;
371                         //print(">>" +locBraceNest);
372                         continue; // no more processing..
373                     }
374                     
375                     
376                     // xxx = new yyy ( {
377                         
378                     // change scope to xxxx
379                     /*
380                     print(JSON.stringify([
381                         this.ts.lookTok(1).data ,
382                         this.ts.lookTok(2).name ,
383                         this.ts.lookTok(3).type ,
384                         this.ts.lookTok(4).data ,
385                         this.ts.lookTok(5).data 
386                     ], null, 4));
387                     */
388                     if ( this.ts.lookTok(1).data == "=" &&
389                         this.ts.lookTok(2).isName(TokenName.NEW) &&
390                         this.ts.lookTok(3).isType(TokenType.NAME)&&
391                         this.ts.lookTok(4).data == "(" &&
392                         this.ts.lookTok(5).data == "{" 
393                         ) {
394                         scopeName = token.data;
395                         if (this.currentDoc != null) {
396                                 GLib.debug("Call addSymbol %s", scopeName);
397                             this.addSymbol(scopeName,false,"OBJECT");
398                             
399                         }
400                         
401                         this.ts.nextTok(); /// =
402                         this.ts.nextTok(); /// new
403                         this.ts.nextTok(); /// yyy
404                         this.ts.nextTok(); /// (
405                         this.ts.nextTok(); /// {
406                             
407                         scopeName = this.fixAlias(aliases,scopeName);
408                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
409                                         scopeName,null
410                                         ); 
411                         this.indexedScopes.set(this.ts.cursor,  fnScope);
412                         scope = fnScope;
413                         this.scopesIn(fnScope);
414                          
415                         locBraceNest++;
416                         //print(">>" +locBraceNest);
417                         
418                         continue; // no more processing..
419                     }
420                     
421
422                      
423                     
424                     
425                     
426                     
427                     // eval can be prefixed with a hint hider for the compresser..
428                     
429                     
430                     if (this.currentDoc != null) {
431                         //print(token.toString());
432                         
433                         // ident : function ()
434                         // ident = function ()
435                         // this.ident = function()
436                         var atype = "OBJECT";
437                         
438                         if (((this.ts.lookTok(1).data == ":" )|| (this.ts.lookTok(1).data == "=")) &&
439                             (this.ts.lookTok(2).isName(TokenName.FUNCTION))
440                             ) {
441                                // this.ts.nextTok();
442                                // this.ts.nextTok();
443                                 atype = "FUNCTION";
444                         }
445                         
446                         //print("ADD SYM:" + atype + ":" + token.toString() + this.ts.lookTok(1).toString() + this.ts.lookTok(2).toString());
447                         var tname = this.ts.lookTok(-1).data == "." ? token.data :    this.fixAlias(aliases,token.data);
448
449                         if (/^this\./.match(tname)) {
450                                 tname = tname.substring(5);
451                         }
452                         GLib.debug("Call addSymbol %s", tname);                        
453                         this.addSymbol( tname, false, atype);
454                         
455
456                         this.currentDoc = null;
457                         
458                         
459                         
460                         
461                         
462                         
463                     }
464                  
465                     
466                     continue; // dont care about other idents..
467                     
468                 }
469                 
470                 //print ("NOT NAME");
471                 
472                 
473                 if (token.isType(TokenType.STRN))   { // THIS WILL NOT HAPPEN HERE?!!?
474                     if (this.currentDoc != null) {
475                         GLib.debug("Call addSymbol %s", token.data.substring(1,token.data.length-1));
476                         this.addSymbol(token.data.substring(1,token.data.length-1),false,"OBJECT");
477                     }
478                 }
479             
480                 // really we only have to deal with object constructs and function calls that change the scope...
481                 
482                 
483                 if (token.isName(TokenName.FUNCTION)) {
484                         GLib.debug("Got Function");
485                     //print("GOT FUNCTION");
486                     // see if we have an unconsumed doc...
487                     
488                         if (this.currentDoc != null) {
489                         GLib.error("Unhandled doc (TOKfunction) %s", token.asString());
490                     }
491                     
492                      
493                      
494                      
495                      
496                     /// foo = function() {} << really it set"s the "this" scope to foo.prototype
497                     //$this$=foo.prototype|$private$|foo.prototype
498         
499                     if (
500                             (this.ts.lookTok(-1).data == "=") && 
501                             (this.ts.lookTok(-2).isType(TokenType.NAME))
502                         ) {
503
504                         scopeName = this.ts.lookTok(-2).data;
505                         GLib.debug("Got %s = Function", scopeName);
506                         this.ts.balance(TokenName.LEFT_PAREN);
507                         token = this.ts.nextTok(); // should be {
508                         //print("FOO=FUNCITON() {}" + this.ts.context() + "\n" + token.toString());
509                         
510                         
511                         scopeName = this.fixAlias(aliases, scopeName);
512                          
513                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
514                                         "$this$="+scopeName+".prototype|$private$|"+scopeName+".prototype",
515                                         null
516                                         ); 
517                         
518                         this.indexedScopes.set(this.ts.cursor, fnScope);
519                         //scope = fnScope;
520                         // this.scopesIn(fnScope);
521                         this.parseScope(fnScope, aliases);
522                         
523                         
524                        
525                         locBraceNest++;
526                         //print(">>" +locBraceNest);
527                         continue; // no more processing..    
528                           
529                         
530                     }
531                         
532                 
533                 // foo = new function() {}
534                         // is this actually used much!?!?! -- 
535                         //$private$
536                         
537                     if (
538                             (this.ts.lookTok(-1).isName(TokenName.NEW)) && 
539                             (this.ts.lookTok(-2).data == "=") &&
540                             (this.ts.lookTok(-3).isName(TokenName.FUNCTION))
541                         ) {
542                         //scopeName = this.ts.look(-3).data;
543                         this.ts.balance(TokenName.LEFT_PAREN);
544                         token = this.ts.nextTok(); // should be {
545                         scopeName = this.fixAlias(aliases, scopeName);
546                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
547                                         "$private$",null
548                                         ); 
549                         
550                         
551                         this.indexedScopes.set(this.ts.cursor,  fnScope);
552                         //scope = fnScope;
553                         // this.scopesIn(fnScope);
554                         this.parseScope(fnScope, aliases);
555                         
556                         locBraceNest++;
557                         //print(">>" +locBraceNest);
558                         continue; // no more processing..    
559                           
560                         
561                     }    
562                    
563                     
564     ///==== check/set isObjectLitAr ??                
565                     
566                     
567                  // foo: function() {}
568                         // no change to scoping..
569                         
570                     //print("checking for : function() {"); 
571                     //print( [this.ts.lookTok(-3).type , this.ts.lookTok(-2).type , this.ts.lookTok(-1).type ].join(":"));
572                     if (
573                             (this.ts.lookTok(-1).data == ":") && 
574                             (this.ts.lookTok(-2).isType(TokenType.NAME)) &&
575                             (this.ts.lookTok(-3).data == "(" || this.ts.lookTok(-3).data== ",") 
576                         ) {
577                         //print("got for : function() {"); 
578                             
579                         //scopeName = this.ts.look(-3).data;
580                         this.ts.balance(TokenName.LEFT_PAREN);
581                         //print(token.toString())
582                         token = this.ts.nextTok(); // should be {
583                         //print(token.toString())
584                         
585                         scopeName = this.fixAlias(aliases, scopeName);
586                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
587                                         "", null
588                                         ); 
589
590                         this.indexedScopes.set(this.ts.cursor, fnScope);
591                         //scope = fnScope;
592                         // this.scopesIn(fnScope);
593                          this.parseScope(fnScope, aliases);
594                         locBraceNest++;
595                         //print(">>" +locBraceNest);
596                         continue; // no more processing..    
597                           
598                     } 
599                /// function foo() {} << really it set"s the "this" scope to foo.prototype
600                         //$this$=foo|$private$
601                         //$this$=foo
602                         
603                     if (
604                             (this.ts.lookTok(1).isType(TokenType.NAME)) 
605                         ) {
606                         //scopeName = this.ts.look(-3).data;
607                         this.ts.balance(TokenName.LEFT_PAREN);
608                         token = this.ts.nextTok(); // should be {
609                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
610                                         "", null
611                                         ); 
612
613                         this.indexedScopes.set(this.ts.cursor, fnScope);
614                         // scope = fnScope;
615                         // this.scopesIn(fnScope);
616                         this.parseScope(fnScope, aliases);
617                         locBraceNest++;
618                         //print(">>" +locBraceNest);
619                         continue; // no more processing..    
620                           
621                     }
622                     
623                      // 0 == FUNCTION...
624                      
625                      // this is used in Roo.util.JSON
626                      // XXXX = new (function() { 
627                      
628                       if (
629                              (this.ts.lookTok(-1).data == "(") &&
630                             (this.ts.lookTok(-2).data == "new" ) &&
631                             (this.ts.lookTok(-3).data == "=") &&
632                             (this.ts.lookTok(-4).isType(TokenType.NAME))
633                         ) {
634                         
635                         
636                         scopeName = this.ts.lookTok(-4).data;
637                         this.ts.balance(TokenName.LEFT_PAREN);
638                         token = this.ts.nextTok(); // should be {
639                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
640                                                 "$this$="+scopeName+".prototype|$private$|"+scopeName+".prototype",null
641                                         ); 
642
643                         this.indexedScopes.set(this.ts.cursor, fnScope);
644                         //scope = ;
645                         // this.scopesIn(fnScope);
646                         this.parseScope(fnScope, aliases);
647                         locBraceNest++;
648                         //print(">>" +locBraceNest);
649                         continue; // no more processing..    
650                           
651                         
652                     }
653                      
654                 // foo = new (function() { }
655                 // (function() { }
656                 // RETURN function(...) {
657                     
658                     if (
659                            // (this.ts.lookTok(-1).tokN == Script.TOKlparen) && 
660                             (!this.ts.lookTok(1).isType(TokenType.NAME))   
661                             
662                         //    (this.ts.lookTok(-2).tokN == Script.TOKnew) &&
663                          //   (this.ts.lookTok(-3).tokN == Script.TOKassign) &&
664                          //   (this.ts.lookTok(-4).tokN == Script.TOKidentifier)
665                         ) {
666                         
667                         //scopeName = this.ts.look(-3).data;
668                         this.ts.balance(TokenName.LEFT_PAREN);
669                         token = this.ts.nextTok(); // should be {
670                         var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
671                                                 "$private$",null
672                                         ); 
673
674                         this.indexedScopes.set(this.ts.cursor, fnScope);
675                         //scope = ;
676                         // this.scopesIn(fnScope);
677                          this.parseScope(fnScope, aliases);
678                         locBraceNest++;
679                         //print(">>" +locBraceNest);
680                         continue; // no more processing..    
681                           
682                         
683                     }
684                     
685                     GLib.error( "dont know how to handle function syntax??\n %s" +
686                                 token.asString());
687                     
688             
689                     
690                     continue;
691                     
692                     
693                     
694                     
695                 } // end checking for TOKfunction
696                     
697                 if (token.data == "{") {
698                     
699                      // foo = { // !var!!!
700                         //$this$=foo|Foo
701                
702                 
703                     if (
704                             (this.ts.lookTok(-1).data == "=") &&
705                             (this.ts.lookTok(-2).isType(TokenType.NAME)) &&
706                             (!this.ts.lookTok(-3).isName(TokenName.VAR))  
707                         ) {
708                             
709                             scopeName = this.ts.lookTok(-2).data;
710                             //print(scopeName);
711                             scopeName = this.fixAlias(aliases, scopeName);
712                             GLib.debug("got %s = {", scopeName);
713                             
714                             //print(this.scopes.length);
715                             var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
716                                                         "$this$=" + scopeName +"|"+scopeName, null
717                                                 ); 
718                             
719                             this.indexedScopes.set(this.ts.cursor, fnScope);
720                             scope = fnScope;
721                             // push the same scope onto the stack..
722                             this.scopesIn(fnScope);
723                             // this.scopesIn(this.scopes[this.scopes.length-1]);
724                             
725                               
726                             locBraceNest++;
727                             //print(">>" +locBraceNest);
728                             continue; // no more processing..   
729                     }
730                     // foo : {
731                     // ?? add |foo| ????
732                       
733                     //print("GOT LBRACE : check for :");
734                     if (
735                             (this.ts.lookTok(-1).data == ":") &&
736                             (this.ts.lookTok(-2).isType(TokenType.NAME)) &&
737                             (!this.ts.lookTok(-3).isName(TokenName.VAR)) 
738                         ) {
739                             
740                             scopeName = this.ts.lookTok(-2).data;
741                             scopeName = this.fixAlias(aliases, scopeName);
742                             var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
743                                                         scopeName, null
744                                                 ); 
745
746                             this.indexedScopes.set(this.ts.cursor, fnScope);
747                             scope = fnScope;
748                             this.scopesIn(fnScope);
749                             
750                             locBraceNest++;
751                             //print(">>" +locBraceNest);
752                             continue; // no more processing..   
753                     }
754                     var fnScope =  new Scope(this.braceNesting, scope, token.id, // was token.n?
755                                                 "", null
756                                 ); 
757
758                     this.indexedScopes.set(this.ts.cursor, fnScope);
759                     scope = fnScope;
760                     this.scopesIn(fnScope);
761                    
762                     locBraceNest++;
763                     //print(">>" +locBraceNest);
764                     continue;
765                     
766                 }
767                 if (token.data == "}") {
768                     
769                      
770                         if (this.currentDoc != null) {
771                                                          GLib.debug("Call addSymbol EMPTY");
772                             this.addSymbol("", true);
773
774                             //throw "Unconsumed Doc: (TOKrbrace)" + this.currentDoc.toSource();
775                         }
776                         
777                        
778                         locBraceNest--;
779                         
780                             //assert braceNesting >= scope.getBraceNesting();
781                         var closescope = this.scopeOut();
782                         
783                         scope = this.scopes.get(this.scopes.size-1);
784                         
785                         //print("<<:" +  locBraceNest)
786                         //print("<<<<<< " + locBraceNest );
787                         if (locBraceNest < 0) {
788                            // print("POPED OF END OF SCOPE!");
789                             // this.scopeOut();   
790                             // var ls = this.scopeOut();
791                             // ls.getUsedSymbols();
792                             return;
793                         }
794                         continue;
795                 }
796               
797                 
798             }
799             
800             
801         }
802      
803          
804         void addSymbol(string in_lastIdent, bool appendIt = false, string atype = "OBJECT")
805         {
806             
807             GLib.debug("addSymbol %s", in_lastIdent);
808             var lastIdent = in_lastIdent;
809             if (this.currentDoc.getTag(DocTagTitle.PRIVATE).size > 0) {
810                 
811               
812                 //print(this.currentDoc.toSource());
813                  this.currentDoc = null;
814                 //print("SKIP ADD SYM:  it"s private");
815                 return;
816             }
817             
818             var token = this.ts.lookTok(0);
819           
820           //  print(this.currentDoc.toSource(););
821             if (this.currentDoc.getTag(DocTagTitle.EVENT).size > 0) {
822                 //?? why does it end up in desc - and not name/...
823                 //print(this.currentDoc.getTag("event")[0]);
824                 lastIdent = "*" + this.currentDoc.getTag(DocTagTitle.EVENT).get(0).desc;
825                 //lastIdent = "*" + lastIdent ;
826             }
827             if (lastIdent.length < 1 && this.currentDoc.getTag(DocTagTitle.PROPERTY).size > 0) {
828                 lastIdent = this.currentDoc.getTag(DocTagTitle.PROPERTY).get(0).name;
829                 //lastIdent = "*" + lastIdent ;
830             }
831             
832             var _s = lastIdent;
833             if (!/\./.match(_s)) {
834                     
835                 //print("WALKER ADDsymbol: " + lastIdent);
836                 
837                 string[] s = {};
838                 GLib.debug("Checking Scopes %d", this.scopes.size);
839                 for (var i = 0; i < this.scopes.size;i++) {
840                     GLib.debug("Scope %s", this.scopes.get(i).ident);
841                         var adds = this.scopes.get(i).ident;
842                         
843                     s = s + adds;
844                 }
845                 s += lastIdent;
846                 
847                 GLib.debug("FULLSCOPE: '%s'" , string.joinv("', '", s));
848                 
849                 
850                 s = string.joinv("|", s).split("|");
851                 //print("FULLSCOPE: " + s);
852              //  print("Walker:ADDSymbol: " + s.join("|") );
853                 var _t = "";
854                  _s = "";
855                 
856                 /// fixme - needs
857                 for (var i = 0; i < s.length;i++) {
858                     
859                     if (s[i].length < 1) {
860                         continue;
861                     }
862                     if ((s[i] == "$private$") || (s[i] == "$global$")) {
863                         _s = "";
864                         continue;
865                     }
866                     if (s[i].length > 5 &&  s[i].substring(0,6) == "$this$") {
867                         var ts = s[i].split("=");
868                         _t = ts[1];
869                         _s = ""; // ??? VERY QUESTIONABLE!!!
870                         continue;
871                     }
872                     // when to use $this$ (probabl for events)
873                     _s += _s.length > 0 ? "." : "";
874                     _s += s[i];
875                 }
876                 GLib.debug("FULLSCOPE: _s=%s (append = %s)" , _s, appendIt? "YES": "no");
877                 
878                 /// calc scope!!
879                 //print("ADDING SYMBOL: "+ s.join("|") +"\n"+ _s + "\n" +Script.prettyDump(this.currentDoc.toSource()));
880                 //print("Walker.addsymbol - add : " + _s);
881                 
882                 
883                 if (appendIt && lastIdent.length < 1) {
884                     
885                     // append, and no symbol???
886                     
887                     // see if it"s a @class
888                     if (this.currentDoc.getTag(DocTagTitle.CLASS).size > 0) {
889                         _s = this.currentDoc.getTag(DocTagTitle.CLASS).get(0).desc;
890                         var symbol = new Symbol.new_populate_with_args(_s, new Gee.ArrayList<string>(),
891                                          "CONSTRUCTOR", this.currentDoc);
892                        
893                         DocParser.addSymbol(symbol);
894                         this.symbols[_s] = symbol;
895                         return;
896                     }
897                     
898                    // if (this.currentDoc.getTag("property").length) {
899                      //   print(Script.pretStringtyDump(this.currentDoc.toSource));
900                     //    throw "Add Prop?";
901                     //}
902
903                     _s = /\.prototype.*$/.replace(_s, _s.length,0, "");
904                     
905                     if (!this.symbols.has_key(_s)) {
906                         //print("Symbol:" + _s);
907                         //print(this.currentDoc.src);
908                         
909                         //throw {
910                         //    name: "ArgumentError", 
911                         //    message: "Trying to append symbol "" + _s + "", but no doc available\n" +
912                         //        this.ts.lookTok(0).toString()
913                         //};
914                         this.currentDoc = null;
915                         return;
916                      
917                     }
918                     GLib.debug("add to symbol  _s=%s  " , _s);    
919                     for (var i =0; i < this.currentDoc.tags.size;i++) {
920                         this.symbols.get(_s).addDocTag(this.currentDoc.tags.get(i));
921                     } 
922                     this.currentDoc = null;
923                     return;
924                 }
925             }    
926             //print("Walker.addsymbol - chkdup: " + _s);
927             if (this.symbols.has_key(_s)) {
928                 
929                 if (this.symbols.get(_s).comment.hasTags) {
930                     // then existing comment doesnt has tags 
931                     //throw {
932                     //    name: "ArgumentError", 
933                      //   message:"DUPLICATE Symbol " + _s + "\n" + token.toString()
934                     //};
935                     return;
936                 }
937                 // otherwise existing comment has tags - overwrite..
938                 
939                 
940             }
941             //print("Walker.addsymbol - ATYPE: " + _s);
942
943
944
945             
946             //print("Walker.addsymbol - add : ");
947             var symbol = new Symbol.new_populate_with_args(
948                         _s, new Gee.ArrayList<string>(), atype, this.currentDoc);
949
950             DocParser.addSymbol(symbol);
951             this.symbols[_s] = symbol;
952             
953              this.currentDoc = null;
954             
955         }
956         
957         
958         
959         
960         void scopesIn  (Scope s)
961         {
962             this.scopes.add(s);
963             //print(">>>" + this.ts.context()  + "\n>>>"+this.scopes.length+":" +this.scopeListToStr());
964             
965         }
966         Scope scopeOut()
967         {
968             
969            // print("<<<" + this.ts.context()  + "\n<<<"+this.scopes.length+":" +this.scopeListToStr());
970             return this.scopes.remove_at(this.scopes.size -1 );
971             
972         }
973         
974         string scopeListToStr ()
975         {
976             string[] s = {};
977             for (var i = 0; i < this.scopes.size;i++) {
978                 s +=(this.scopes[i].ident);
979             }
980             return  string.joinv("\n\t",s);
981             
982         }
983         
984     }
985     
986      
987 }