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
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
174                         //throw "Unconsumed Doc (TOKwhitespace): " + this.currentDoc.toSource();
175                     }
176                     
177                     
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                 
242               
243                 // extends scoping  *** not sure if the can be x = Roo.apply(....)
244                 // xxx.extends(a,b, {
245                     // $this$=b|b.prototype
246                 // xxx.apply(a, {
247                     // a  << scope
248                 // xxx.applyIf(a, {
249                     // a  << scope
250                 if (token.type == 'NAME') {
251                     
252                     //print("TOK(ident)"+ token.toString());
253                     
254                     
255                        
256                     
257                     
258                     if (/\.extend$/.test(token.data) &&
259                         this.ts.lookTok(1).data == '(' &&
260                         this.ts.lookTok(2).type == 'NAME' &&
261                         this.ts.lookTok(3).data == ',' &&
262                         this.ts.lookTok(4).type == 'NAME' &&
263                         this.ts.lookTok(5).data == ',' &&
264                         this.ts.lookTok(6).data == '{' 
265                            
266                         ) {
267                         // ignore test for ( a and ,
268                         this.ts.nextTok(); /// (
269                         token = this.ts.nextTok(); // a
270                         scopeName = token.data;
271                         
272                         if (this.currentDoc) {
273                             this.addSymbol(scopeName,false,'OBJECT');
274
275                         }
276                         this.ts.nextTok(); // ,
277                         this.ts.nextTok(); // b
278                         
279                         
280                         this.ts.nextTok(); // ,
281                         token = this.ts.nextTok(); // {
282                             
283                         scopeName = fixAlias(scopeName);
284                         
285                         var fnScope = new Scope(this.braceNesting, scope, token.n, 
286                             '$this$=' + scopeName  + '|'+scopeName+'.prototype');
287                         this.indexedScopes[this.ts.cursor] = fnScope;
288                         scope = fnScope;
289                         this.scopesIn(fnScope);
290                        
291                         locBraceNest++;
292                         //print(">>" +locBraceNest);
293                         continue; // no more processing..
294                         
295                     }
296                     
297                     // a = Roo.extend(parentname, {
298                         
299                      if (/\.extend$/.test(token.data) &&
300                         this.ts.lookTok(-2).type == 'NAME'  &&
301                         this.ts.lookTok(-1).data == '=' &&
302                         this.ts.lookTok(1).data == '(' &&
303                         this.ts.lookTok(2).type == 'NAME' &&
304                         this.ts.lookTok(3).data == ',' &&
305                         this.ts.lookTok(4).data == '{' 
306                         ) {
307                         // ignore test for ( a and ,
308                         token = this.ts.lookTok(-2);
309                         scopeName = token.data;
310                         if (this.currentDoc) {
311                             this.addSymbol(scopeName,false,'OBJECT');
312
313                         }
314                         this.ts.nextTok(); /// (
315                         this.ts.nextTok(); // parent
316                         
317                         this.ts.nextTok(); // ,
318                         token =  this.ts.nextTok(); // {
319                              
320                         
321                         scopeName = fixAlias(scopeName);
322                         var fnScope = new Scope(this.braceNesting, scope, token.n, 
323                             '$this$=' + scopeName  + '|'+scopeName+'.prototype');
324                         this.indexedScopes[this.ts.cursor] = fnScope;
325                         scope = fnScope;
326                         this.scopesIn(fnScope);
327                        
328                         locBraceNest++;
329                         //print(">>" +locBraceNest);
330                         continue; // no more processing..
331                         
332                     }
333                     
334                     
335                      // apply ( XXXX,  {
336                     /*
337                     print(JSON.stringify([
338                         token.data,
339                         this.ts.lookTok(1).data ,
340                         this.ts.lookTok(2).type ,
341                         this.ts.lookTok(3).data ,
342                         this.ts.lookTok(4).data 
343                     ], null, 4));
344                     */
345                     
346                     if (/\.(applyIf|apply)$/.test(token.data) && 
347                         this.ts.lookTok(1).data == '('  &&
348                         this.ts.lookTok(2).type == 'NAME' &&
349                         this.ts.lookTok(3).data == ','  &&
350                         this.ts.lookTok(4).data == '{' 
351                         
352                         ) {
353                         this.ts.nextTok(); /// (
354                          
355                         //print("GOT : applyIF!"); 
356                          
357                         token = this.ts.nextTok(); // b
358                         scopeName = token.data;
359                         
360                                       
361                         if (this.currentDoc) {
362                             this.addSymbol(scopeName,false,'OBJECT');
363                         }
364                      
365
366                         
367                         this.ts.nextTok(); /// ,
368                         this.ts.nextTok(); // {
369                         scopeName = fixAlias(scopeName);
370                         var fnScope = new Scope(this.braceNesting, scope, token.n, scopeName);
371                         this.indexedScopes[this.ts.cursor] = fnScope;
372                         scope = fnScope;
373                         this.scopesIn(fnScope);
374                          
375                         locBraceNest++;
376                         //print(">>" +locBraceNest);
377                         continue; // no more processing..
378                     }
379                     
380                     
381                     // xxx = new yyy ( {
382                         
383                     // change scope to xxxx
384                     /*
385                     print(JSON.stringify([
386                         this.ts.lookTok(1).data ,
387                         this.ts.lookTok(2).name ,
388                         this.ts.lookTok(3).type ,
389                         this.ts.lookTok(4).data ,
390                         this.ts.lookTok(5).data 
391                     ], null, 4));
392                     */
393                     if ( this.ts.lookTok(1).data == '=' &&
394                         this.ts.lookTok(2).name == 'NEW' &&
395                         this.ts.lookTok(3).type == 'NAME' &&
396                         this.ts.lookTok(4).data == '(' &&
397                         this.ts.lookTok(5).data == '{' 
398                         ) {
399                         scopeName = token.data;
400                         if (this.currentDoc) {
401                             this.addSymbol(scopeName,false,'OBJECT');
402                             
403                         }
404                         
405                         this.ts.nextTok(); /// =
406                         this.ts.nextTok(); /// new
407                         this.ts.nextTok(); /// yyy
408                         this.ts.nextTok(); /// (
409                         this.ts.nextTok(); /// {
410                             
411                         scopeName = fixAlias(scopeName);
412                         var fnScope = new Scope(this.braceNesting, scope, token.n, scopeName);
413                         this.indexedScopes[this.ts.cursor] = fnScope;
414                         scope = fnScope;
415                         this.scopesIn(fnScope);
416                          
417                         locBraceNest++;
418                         //print(">>" +locBraceNest);
419                         
420                         continue; // no more processing..
421                     }
422                     
423
424                     
425                     
426                     
427                     
428                     
429                     
430                     
431                     
432                     
433                     
434                     
435                     
436                     
437                     
438                     
439                     
440                     
441                     // eval can be prefixed with a hint hider for the compresser..
442                     if ((token.data == 'eval') || /\.eval$/.test(token.data)) {
443                         this.currentDoc = false;
444                         continue;
445                     }
446                     
447                     if (this.currentDoc) {
448                         //print(token.toString());
449                         
450                         // ident : function ()
451                         // ident = function ()
452                         var atype = 'OBJECT';
453                         
454                         if (((this.ts.lookTok(1).data == ':' )|| (this.ts.lookTok(1).data == '=')) &&
455                             (this.ts.lookTok(2).name == "FUNCTION")
456                             ) {
457                                 atype = 'FUNCTION';
458                         }
459                         
460                         //print("ADD SYM:" + atype + ":" + token.toString() + this.ts.lookTok(1).toString() + this.ts.lookTok(2).toString());
461                         
462                         this.addSymbol(
463                             this.ts.lookTok(-1).data == '.' ? token.data :    fixAlias(token.data),
464                             false,
465                             atype);
466                         
467                     }
468                  
469                     
470                     continue; // dont care about other idents..
471                     
472                 }
473                 
474                 //print ("NOT NAME");
475                 
476                 
477                 if (token.type == "STRN")   {
478                     if (this.currentDoc) {
479                         this.addSymbol(token.data.substring(1,token.data.length-1),false,'OBJECT');
480
481                     }
482                 }
483             
484                 // really we only have to deal with object constructs and function calls that change the scope...
485                 
486                 
487                  if (token.name == 'FUNCTION') {
488                     //print("GOT FUNCTION");
489                     // see if we have an unconsumed doc...
490                     
491                     if (this.currentDoc) {
492                             print(this.ts.dump(this.ts.cursor-20, this.ts.cursor+20));
493                             throw {
494                                 name: "ArgumentError", 
495                                 message: "Unhandled doc (TOKfunction)" + token.toString()
496                             };
497                             
498                             //this.addSymbol(this.currentDoc.getTag('class')[0].name, true);
499
500                             //throw "Unconsumed Doc: (TOKrbrace)" + this.currentDoc.toSource();
501                     }
502                     
503                      
504                      
505                      
506                      
507                     /// foo = function() {} << really it set's the 'this' scope to foo.prototype
508                     //$this$=foo.prototype|$private$|foo.prototype
509         
510                     if (
511                             (this.ts.lookTok(-1).data == '=') && 
512                             (this.ts.lookTok(-2).type == 'NAME')
513                         ) {
514                         scopeName = this.ts.lookTok(-2).data;
515                         this.ts.balance('(');
516                         token = this.ts.nextTok(); // should be {
517                         //print("FOO=FUNCITON() {}" + this.ts.context() + "\n" + token.toString());
518                         
519                         
520                         scopeName = fixAlias(scopeName);
521                         var fnScope = new Scope(this.braceNesting, scope, token.n, 
522                             '$this$='+scopeName+'.prototype|$private$|'+scopeName+'.prototype');
523                             
524                         this.indexedScopes[this.ts.cursor] = fnScope;
525                         //scope = fnScope;
526                         //this.scopesIn(fnScope);
527                         this.parseScope(fnScope, aliases);
528                         
529                         
530                        
531                         locBraceNest++;
532                         //print(">>" +locBraceNest);
533                         continue; // no more processing..    
534                           
535                         
536                     }
537                         
538                 
539                 // foo = new function() {}
540                         // is this actually used much!?!?!
541                         //$private$
542                         
543                     if (
544                             (this.ts.lookTok(-1).name == 'NEW') && 
545                             (this.ts.lookTok(-2).data == '=') &&
546                             (this.ts.lookTok(-3).type = 'FUNCTION')
547                         ) {
548                         //scopeName = this.ts.look(-3).data;
549                         this.ts.balanceN(Script.TOKlparen);
550                         token = this.ts.nextTok(); // should be {
551                             scopeName = fixAlias(scopeName);
552                         var fnScope = new Scope(this.braceNesting, scope, token.n, '$private$');
553                         this.indexedScopes[this.ts.cursor] = fnScope;
554                         //scope = fnScope;
555                         //this.scopesIn(fnScope);
556                         this.parseScope(fnScope, aliases);
557                         
558                         locBraceNest++;
559                         //print(">>" +locBraceNest);
560                         continue; // no more processing..    
561                           
562                         
563                     }    
564                    
565                     
566     ///==== check/set isObjectLitAr ??                
567                     
568                     
569                  // foo: function() {}
570                         // no change to scoping..
571                         
572                     //print("checking for : function() {"); 
573                     //print( [this.ts.lookTok(-3).type , this.ts.lookTok(-2).type , this.ts.lookTok(-1).type ].join(":"));
574                     if (
575                             (this.ts.lookTok(-1).data == ':') && 
576                             (this.ts.lookTok(-2).type == 'NAME') &&
577                             (this.ts.lookTok(-3).data == '(' || this.ts.lookTok(-3).data== ',') 
578                         ) {
579                         //print("got for : function() {"); 
580                             
581                         //scopeName = this.ts.look(-3).data;
582                         this.ts.balance('(');
583                         //print(token.toString())
584                         token = this.ts.nextTok(); // should be {
585                         //print(token.toString())
586                         scopeName = fixAlias(scopeName);
587                         var fnScope = new Scope(this.braceNesting, scope, token.n, '');
588                         this.indexedScopes[this.ts.cursor] = fnScope;
589                         //scope = fnScope;
590                         //this.scopesIn(fnScope);
591                          this.parseScope(fnScope, aliases);
592                         locBraceNest++;
593                         //print(">>" +locBraceNest);
594                         continue; // no more processing..    
595                           
596                     } 
597                /// function foo() {} << really it set's the 'this' scope to foo.prototype
598                         //$this$=foo|$private$
599                         //$this$=foo
600                         
601                     if (
602                             (this.ts.lookTok(1).type == 'NAME') 
603                         ) {
604                         //scopeName = this.ts.look(-3).data;
605                         this.ts.balance('(');
606                         token = this.ts.nextTok(); // should be {
607                             
608                         var fnScope = new Scope(this.braceNesting, scope, token.n, '');
609                         this.indexedScopes[this.ts.cursor] = fnScope;
610                         //scope = fnScope;
611                         //this.scopesIn(fnScope);
612                         this.parseScope(fnScope, aliases);
613                         locBraceNest++;
614                         //print(">>" +locBraceNest);
615                         continue; // no more processing..    
616                           
617                     }
618                     
619                      
620                 // foo = new (function() { }
621                 // (function() { }
622                 // RETURN function(...) {
623                     
624                     if (
625                            // (this.ts.lookTok(-1).tokN == Script.TOKlparen) && 
626                             (this.ts.lookTok(1).name != 'NAME')   
627                             
628                         //    (this.ts.lookTok(-2).tokN == Script.TOKnew) &&
629                          //   (this.ts.lookTok(-3).tokN == Script.TOKassign) &&
630                          //   (this.ts.lookTok(-4).tokN == Script.TOKidentifier)
631                         ) {
632                         //scopeName = this.ts.look(-3).data;
633                         this.ts.balance('(');
634                         token = this.ts.nextTok(); // should be {
635                         var fnScope = new Scope(this.braceNesting, scope, token.n, '$private$');
636                         this.indexedScopes[this.ts.cursor] = fnScope;
637                         //scope = ;
638                         //this.scopesIn(fnScope);
639                          this.parseScope(fnScope, aliases);
640                         locBraceNest++;
641                         //print(">>" +locBraceNest);
642                         continue; // no more processing..    
643                           
644                         
645                     }
646                     
647                     
648                     print(this.ts.dump(this.ts.cursor-20, this.ts.cursor+20));
649                     throw {
650                         name: "ArgumentError", 
651                         message: "dont know how to handle function syntax??"
652                     };
653             
654                     
655                     continue;
656                     
657                     
658                     
659                     
660                 } // end checking for TOKfunction
661                     
662                 if (token.data == '{') {
663                     
664                      // foo = { // !var!!!
665                         //$this$=foo|Foo
666                
667                 
668                     if (
669                             (this.ts.lookTok(-1).data == '=') &&
670                             (this.ts.lookTok(-2).type == 'NAME') &&
671                             (this.ts.lookTok(-3).nane != 'VAR')  
672                         ) {
673                             
674                             scopeName = this.ts.look(-2).data;
675                             scopeName = fixAlias(scopeName);
676                             var fnScope = new Scope(this.braceNesting, scope, token.n, 
677                                 '$this$='+scopeName + '|'+scopeName
678                             );
679                             this.indexedScopes[this.ts.cursor] = fnScope;
680                             scope = fnScope;
681                             this.scopesIn(fnScope);
682                             
683                               
684                             locBraceNest++;
685                             //print(">>" +locBraceNest);
686                             continue; // no more processing..   
687                     }
688                     // foo : {
689                     // ?? add |foo| ????
690                       
691                     //print("GOT LBRACE : check for :");
692                     if (
693                             (this.ts.lookTok(-1).data == ':') &&
694                             (this.ts.lookTok(-2).type == 'NAME') &&
695                             (this.ts.lookTok(-3).name != 'VAR') 
696                         ) {
697                             
698                             scopeName = this.ts.lookTok(-2).data;
699                             scopeName = fixAlias(scopeName);
700                             var fnScope = new Scope(this.braceNesting, scope, token.n, scopeName);
701                             this.indexedScopes[this.ts.cursor] = fnScope;
702                             scope = fnScope;
703                             this.scopesIn(fnScope);
704                             
705                             locBraceNest++;
706                             //print(">>" +locBraceNest);
707                             continue; // no more processing..   
708                     }
709                     var fnScope = new Scope(this.braceNesting, scope, token.n, '');
710                     this.indexedScopes[this.ts.cursor] = fnScope;
711                     scope = fnScope;
712                     this.scopesIn(fnScope);
713                    
714                     locBraceNest++;
715                     //print(">>" +locBraceNest);
716                     continue;
717                     
718                 }
719                 if (token.data == '{') {
720                     
721                      
722                         if (this.currentDoc) {
723                             this.addSymbol('', true);
724
725                             //throw "Unconsumed Doc: (TOKrbrace)" + this.currentDoc.toSource();
726                         }
727                         
728                        
729                         locBraceNest--;
730                         
731                             //assert braceNesting >= scope.getBraceNesting();
732                         var closescope = this.scopeOut();   
733                         scope = this.scopes[this.scopes.length-1];
734                         //print("<<:" +  locBraceNest)
735                         //print("<<<<<< " + locBraceNest );
736                         if (locBraceNest < 0) {
737                            // print("POPED OF END OF SCOPE!");
738                             ///this.scopeOut();   
739                             //var ls = this.scopeOut();
740                             //ls.getUsedSymbols();
741                             return;
742                         }
743                         continue;
744                 }
745               
746                 
747             }
748             
749             
750         },
751      
752          
753         addSymbol: function(lastIdent, appendIt, atype )
754         {
755             //print("Walker.addSymbol : " + lastIdent);
756             
757             /*if (!this.currentDoc.tags.length) {
758                 
759               
760                 //print(this.currentDoc.toSource());
761                 //  this.currentDoc = false;
762                 
763                 print("SKIP ADD SYM: no tags");
764                 print(this.currentDoc.src);
765                 return;
766             }
767             */
768             if (this.currentDoc.getTag('private').length) {
769                 
770               
771                 //print(this.currentDoc.toSource());
772                  this.currentDoc = false;
773                 //print("SKIP ADD SYM:  it's private");
774                 return;
775             }
776             
777             var token = this.ts.lookTok(0);
778             if (typeof(appendIt) == 'undefined') {
779                 appendIt= false;
780             }
781           //  print(this.currentDoc.toSource(););
782             if (this.currentDoc.getTag('event').length) {
783                 //?? why does it end up in desc - and not name/...
784                 //print(this.currentDoc.getTag('event')[0]);
785                 lastIdent = '*' + this.currentDoc.getTag('event')[0].desc;
786                 //lastIdent = '*' + lastIdent ;
787             }
788             if (!lastIdent.length && this.currentDoc.getTag('property').length) {
789                 lastIdent = this.currentDoc.getTag('property')[0].name;
790                 //lastIdent = '*' + lastIdent ;
791             }
792             
793             var _s = lastIdent;
794             if (!/\./.test(_s)) {
795                     
796                 //print("WALKER ADDsymbol: " + lastIdent);
797                 
798                 var s = [];
799                 for (var i = 0; i < this.scopes.length;i++) {
800                     s.push(this.scopes[i].ident);
801                 }
802                 s.push(lastIdent);
803                 
804                 var s = s.join('|').split('|');
805                //print("Walker:ADDSymbol: " + s.join('|') );
806                 var _t = '';
807                  _s = '';
808                 
809                 /// fixme - needs
810                 for (var i = 0; i < s.length;i++) {
811                     
812                     if (!s[i].length) {
813                         continue;
814                     }
815                     if ((s[i] == '$private$') || (s[i] == '$global$')) {
816                         _s = '';
817                         continue;
818                     }
819                     if (s[i].substring(0,6) == '$this$') {
820                         var ts = s[i].split('=');
821                         _t = ts[1];
822                         continue;
823                     }
824                     // when to use $this$ (probabl for events)
825                     _s += _s.length ? '.' : '';
826                     _s += s[i];
827                 }
828                     
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                         this.ts.dump(this.ts.cursor -20, this.ts.cursor + 20);
857                         throw {
858                             name: "ArgumentError", 
859                             message: "Trying to append symbol '" + _s + "', but no doc available"
860                         };
861
862                      
863                     }
864                         
865                     for (var i =0; i < this.currentDoc.tags.length;i++) {
866                         this.symbols[_s].addDocTag(this.currentDoc.tags[i]);
867                     }
868                     this.currentDoc = false;
869                     return;
870                 }
871             }    
872             //print("Walker.addsymbol - chkdup: " + _s);
873             if (typeof(this.symbols[_s]) != 'undefined') {
874                 
875                 if (this.symbols[_s].comment.hasTags) {
876                     // then existing comment doesnt has tags 
877                     throw {
878                         name: "ArgumentError", 
879                         message:"DUPLICATE Symbol " + _s
880                     };
881                      
882                 }
883                 // otherwise existing comment has tags - overwrite..
884                 
885                 
886             }
887             //print("Walker.addsymbol - ATYPE: " + _s);
888
889             if (typeof(atype) == "undefined") {
890                 atype = 'OBJECT'; //this.currentDoc.getTag('class').length ? 'OBJECT' : 'FUNCTION';;
891                }
892             
893             //print("Walker.addsymbol - add : ");
894             var symbol = new Symbol(_s, [], atype, this.currentDoc);
895             Parser       = imports.Parser.Parser;
896             Parser.addSymbol(symbol);
897             this.symbols[_s] = symbol;
898             
899              this.currentDoc = false;
900             
901         },
902         
903         
904         
905         
906         scopesIn : function(s)
907         {
908             this.scopes.push(s);
909             //print(">>>" + this.ts.context()  + "\n>>>"+this.scopes.length+":" +this.scopeListToStr());
910             
911         },
912         scopeOut : function()
913         {
914             
915            // print("<<<" + this.ts.context()  + "\n<<<"+this.scopes.length+":" +this.scopeListToStr());
916             return this.scopes.pop();
917             
918         },
919         
920         scopeListToStr : function()
921         {
922             var s = [];
923             for (var i = 0; i < this.scopes.length;i++) {
924                 s.push(this.scopes[i].ident);
925             }
926             return  s.join('\n\t');
927             
928         }
929         
930     
931     
932      
933 });