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