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