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