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