Fix #6894 - debugging generator
[roojspacker] / roojspacker / Symbol.vala
1  
2 /**
3         Create a new Symbol.
4         @class Represents a symbol in the source code.
5  */
6
7  
8 namespace JSDOC {
9
10
11         public  class Symbol : Object
12         {
13                 // debugging?
14                 
15                 
16                 public static bool regex_init = false;
17                 
18
19                 private string private_string_name = "";
20                 private string _assigned_name = "";
21                 // called by symbolset...
22                 public string private_name {
23                 set {
24                                 this._assigned_name = name;
25                                 var n = /^_global_[.#-]/.replace(value, value.length, 0, "");
26                         n =  /\.prototype\.?/.replace(n,n.length, 0, "#");
27                         while (true) {
28                                 if (!n.has_suffix("#")) {
29                                         break;
30                                         }
31                                         n = n.substring(0, n.length-1);
32                                 }
33                         
34                         this.private_string_name = n;
35                 }
36                 
37                 }
38                  
39         public string name {
40                 get { return this.private_string_name; }
41                 }
42                 
43       
44         string defaultValue = "";        
45                 private Gee.ArrayList<DocTag> private_doctag_params = null;
46
47                 private Gee.ArrayList<DocTag> private_params{
48                         set  {
49                                 if (this.private_doctag_params == null) {
50                                         this.private_doctag_params = new Gee.ArrayList<DocTag>();
51                                 }
52                                 for (var i = 0; i < value.size; i++) {
53                                    
54                                     this.private_doctag_params.add(value.get(i));
55                                 }
56                                 //this.params = this._params;
57                         }
58                 }
59      
60                 Gee.ArrayList<string> private_string_params{
61                         set  {
62                                 if (this.private_doctag_params == null) {
63                                         this.private_doctag_params = new Gee.ArrayList<DocTag>();
64                                 }
65                                 for (var i = 0; i < value.size; i++) {
66
67                                     //var ty = v[i].hasOwnProperty('type') ? v[i].type : '';
68                                     this.private_doctag_params.add( new DocTag(value.get(i)));
69                                            
70                                    //"param"+((ty)?" {"+ty+"}":"")+" "+v.get(i).name);
71                                     
72                                 }
73                                 
74                         }
75                 }
76                 public Gee.ArrayList<DocTag> params {
77                         get {
78                                 if (this.private_doctag_params == null) {
79                                         this.private_doctag_params = new Gee.ArrayList<DocTag>();
80                                 }
81                                 return this.private_doctag_params;
82                         }
83                 
84                 }
85
86                 public Gee.ArrayList<string>  augments ;  
87                 
88
89                 private Gee.ArrayList<DocTag>  exceptions ;
90
91                 //public Gee.ArrayList<DocTag>  inherits; 
92                 public Gee.ArrayList<Symbol>  methods;
93
94                 public Gee.ArrayList<Symbol> properties;
95                 private Gee.ArrayList<string> requires;
96                 public Gee.ArrayList<DocTag> returns;
97                 private Gee.ArrayList<string> see ;
98
99                 public Gee.ArrayList<string> childClasses;
100                 public Gee.ArrayList<string> inheritsFrom;
101         public Gee.HashMap<string,DocTag>cfgs;
102         
103         
104         public DocComment comment;
105                 
106         //$args : [], // original arguments used when constructing.
107         //string addOn = "";
108         public string alias = "";
109         
110         string author = "";
111         string classDesc = "";
112
113         string deprecated = "";
114         public string desc = "";
115         //events : false,
116         string example = "";
117         
118
119         public string isa = "OBJECT"; // OBJECT//FUNCTION
120         
121         public bool isEvent = false;
122         public bool isConstant = false;
123         public bool isIgnored = false;
124         public bool isInner = false;
125         public bool isNamespace = false;
126         public bool isPrivate = false;
127         public bool isStatic = false;
128         
129         public string memberOf = "";
130
131                 public string asString()
132                 {
133                         return "NAME: %s:%s   ASNAME: %s : %s%s%s%s".printf(
134                                 this.memberOf,
135                                 this.name,
136                                 this._assigned_name,
137                                 isStatic ? "static": "",
138                                 isEvent ? "EV": "",
139                                 isConstant ? "CO": "",
140                                 isNamespace ? "NS": ""
141                         );
142                                 
143                 
144                 }
145
146        
147         string since = "";
148
149         string type = "";
150         string version = "";
151        
152         public static string srcFile = "";
153         
154         
155         
156         public void initArrays()
157         {
158             // only initialize arrays / objects..
159
160             
161             //this.params = [];
162             //this.$args = [];
163             
164             //this.events = [];
165             this.exceptions = new Gee.ArrayList<DocTag>();
166             //this.inherits = new Gee.ArrayList<DocTag>();
167             //
168             this.isa = "OBJECT"; // OBJECT//FUNCTION
169             this.methods = new Gee.ArrayList<Symbol>();
170             //this.private_params = new Gee.ArrayList<DocTag>();
171             this.properties = new Gee.ArrayList<Symbol>();
172             this.requires = new Gee.ArrayList<string>();
173             this.returns = new Gee.ArrayList<DocTag>();
174             this.see = new Gee.ArrayList<string>();
175             this.augments = new Gee.ArrayList<string>();
176  
177             
178             this.cfgs = new Gee.HashMap<string,DocTag>();
179             // derived later?
180             this.inheritsFrom = new Gee.ArrayList<string>();
181
182             this.childClasses = new Gee.ArrayList<string>();
183              
184             this.comment = new DocComment();
185             this.comment.isUserComment =  false;
186             
187                
188         }
189                 
190                 public Symbol.new_builtin(string name)
191                 {
192             
193             this.initArrays();
194             this.srcFile = JSDOC.DocParser.currentSourceFile;
195                         this.private_name =  name ;
196                         this.alias = this.name;
197                         this.isa = "CONSTRUCTOR";
198                         this.comment = new DocComment("");
199                         this.comment.isUserComment =  false;
200                         this.isNamespace = false;
201                         this.srcFile = "";
202                         this.isPrivate = false;
203                         // init arrays....
204                         
205                         
206                         
207                 }
208                 
209
210  
211
212         public Symbol.new_populate_with_args(
213                 string  name,
214                 Gee.ArrayList<string> params, // fixme???
215                 string isa,
216                 DocComment comment
217         ) {
218            
219             this.initArrays();
220            // this.$args = arguments;
221             //println("Symbol created: " + isa + ":" + name);
222             this.private_name = name;
223             this.alias = this.name;
224             this.private_string_params = params; 
225             this.isa = (isa == "VIRTUAL")? "OBJECT":isa;
226             this.comment =  comment;
227             
228             this.srcFile = DocParser.currentSourceFile;
229             
230            
231             
232             if (this.is("FILE") && this.alias.length < 1) { // this will never hapen???
233                         this.alias = this.srcFile;
234                 }
235
236             this.tagsFromComment();
237             
238         }
239
240         void tagsFromComment() {
241             // @author
242             var authors = this.comment.getTag(DocTagTitle.AUTHOR);
243             if (authors.size > 0) {
244                         // turns author into a string....
245                         this.author = "";
246                 foreach(var a in authors) {
247                     this.author += (this.author == "") ? "": ", ";
248                     this.author += a.desc;
249                 }
250             }
251             
252             /*~t
253                 assert("testing Symbol");
254                 
255                 requires("../lib/JSDOC/DocComment.js");
256                 requires("../frame/String.js");
257                 requires("../lib/JSDOC/DocTag.js");
258
259                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@author Joe Smith*"+"/"));
260                 assertEqual(sym.author, "Joe Smith", "@author tag, author is found.");
261             */
262             // @desc
263             var mth = this.comment.getTag(DocTagTitle.METHOD);
264             if (mth.size  > 0) {
265                 this.isa = "FUNCTION";
266             }
267             // @desc
268             var descs = this.comment.getTag(DocTagTitle.DESC);
269             if (descs.size>  0) {
270                 this.desc = "";
271                 foreach(var d in descs) {
272                     this.desc = this.desc == "" ? "": "\n";
273                     this.desc += d.desc;
274                 }
275
276             }
277             
278             /*~t
279                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@desc This is a description.*"+"/"));
280                 assertEqual(sym.desc, "This is a description.", "@desc tag, description is found.");
281             */
282             
283             // @overview
284             if (this.is("FILE")) {
285                 if (this.alias.length < 1) this.alias = this.srcFile;
286                 
287                 var overviews = this.comment.getTag(DocTagTitle.OVERVIEW);
288                 if (overviews.size > 0) {
289                     foreach(var d in overviews) {
290                         this.desc = this.desc == "" ? "": "\n";
291                         this.desc += d.desc;
292                     }
293                 }
294             }
295             
296             /*~t
297                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@overview This is an overview.*"+"/"));
298                 assertEqual(sym.desc, "\nThis is an overview.", "@overview tag, description is found.");
299             */
300             
301             // @since
302             var sinces = this.comment.getTag(DocTagTitle.SINCE);
303             if (sinces.size > 0) {
304                 this.since = "";
305                 foreach(var d in sinces) {
306                     this.since = this.since == "" ? "": "\n";
307                     this.since += d.desc;
308                 }
309             }
310             
311             /*~t
312                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@since 1.01*"+"/"));
313                 assertEqual(sym.since, "1.01", "@since tag, description is found.");
314             */
315             
316             // @constant
317             if (this.comment.getTag(DocTagTitle.CONSTANT).size > 0) {
318                 this.isConstant = true;
319                 this.isa = "OBJECT";
320             }
321             
322             /*~t
323                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@constant*"+"/"));
324                 assertEqual(sym.isConstant, true, "@constant tag, isConstant set.");
325             */
326             
327             // @version
328             var versions = this.comment.getTag(DocTagTitle.VERSION);
329             if (versions.size > 0 ) {
330                 this.version = "";
331                  foreach(var d in versions) {
332                     this.version = this.version == "" ? "": "\n";
333                     this.version += d.desc;
334                 }
335             }
336             
337             /*~t
338                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@version 2.0x*"+"/"));
339                 assertEqual(sym.version, "2.0x", "@version tag, version is found.");
340             */
341             
342             // @deprecated
343             var deprecateds = this.comment.getTag(DocTagTitle.DEPRECATED);
344             if (deprecateds.size > 0) {
345                 this.deprecated = "";
346                  foreach(var d in deprecateds) {
347                     this.deprecated = this.deprecated == "" ? "": "\n";
348                     this.deprecated += d.desc;
349                 }
350             }
351             
352             /*~t
353                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@deprecated Use other method.*"+"/"));
354                 assertEqual(sym.deprecated, "Use other method.", "@deprecated tag, desc is found.");
355             */
356             
357             // @example
358             var examples = this.comment.getTag(DocTagTitle.EXAMPLE);
359             if (examples.size > 0) {
360                 this.example = examples.get(0).desc;
361             }
362             
363             /*~t
364                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@example This\n  is an example.*"+"/"));
365                 assertEqual(sym.example, "This\n  is an example.", "@deprecated tag, desc is found.");
366             */
367             
368             // @see
369             var sees = this.comment.getTag(DocTagTitle.SEE);
370             if (sees.size > 0) {
371                  
372                 foreach(var s in sees) {
373                     this.see.add(s.desc);
374                 }
375           }
376             
377             /*~t
378                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@see The other thing.*"+"/"));
379                 assertEqual(sym.see, "The other thing.", "@see tag, desc is found.");
380             */
381             
382             // @class
383             var classes = this.comment.getTag(DocTagTitle.CLASS);
384             if (classes.size > 0) {
385                 //print(JSON.stringify(this,null,4));
386                 this.isa = "CONSTRUCTOR";
387                 this.classDesc = classes[0].desc; // desc can't apply to the constructor as there is none.
388                 //if (!this.classDesc.leg) {
389                 //    this.classDesc = this.desc;
390                 //   }
391                 
392                 
393             }
394             
395             /*~t
396                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@class This describes the class.*"+"/"));
397                 assertEqual(sym.isa, "CONSTRUCTOR", "@class tag, makes symbol a constructor.");
398                 assertEqual(sym.classDesc, "This describes the class.", "@class tag, class description is found.");
399             */
400             
401             // @namespace
402             var namespaces = this.comment.getTag(DocTagTitle.NAMESPACE);
403             if (namespaces.size > 0) {
404                 this.classDesc = namespaces[0].desc+"\n"+this.desc; // desc can't apply to the constructor as there is none.
405                 this.isNamespace = true;
406             }
407             
408             /*~t
409                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@namespace This describes the namespace.*"+"/"));
410                 assertEqual(sym.classDesc, "This describes the namespace.\n", "@namespace tag, class description is found.");
411             */
412             
413             // @param
414             var params = this.comment.getTag(DocTagTitle.PARAM);
415             if (params.size > 0) {
416                 // user-defined params overwrite those with same name defined by the parser
417                 var thisParams = params;
418
419                 if (thisParams.size == 0) { // none exist yet, so just bung all these user-defined params straight in
420                     this.private_params = params;
421                 }
422                 else { // need to overlay these user-defined params on to existing parser-defined params
423                     for (var i = 0, l = params.size; i < l; i++) {
424                         if (thisParams.size <= i) {
425                                 var np = thisParams.get(i);
426                                 
427                             if (np.type.length > 0) np.type = params[i].type;
428                             np.name = params[i].name;
429                             np.desc = params[i].desc;
430                             np.isOptional = params[i].isOptional;
431                             np.defaultValue = params[i].defaultValue;
432                             //thisParams.set(i, np); ///?? needed OO ?
433                         }
434                         else thisParams.set(i, params[i]);
435                     }
436                     this.private_params = thisParams;
437                 }
438             }
439             
440             
441             
442             // @constructor
443             if (this.comment.getTag(DocTagTitle.CONSTRUCTOR).size > 0) {
444                 this.isa = "CONSTRUCTOR";
445             }
446             
447          
448             
449             // @static
450             if (this.comment.getTag(DocTagTitle.STATIC).size > 0) {
451                 this.isStatic = true;
452                 if (this.isa == "CONSTRUCTOR") {
453                     this.isNamespace = true;
454                 }
455             }
456             
457                 // @static
458             if (this.comment.getTag(DocTagTitle.SINGLETON).size > 0) {
459                 this.isStatic = true;
460                 //print('------------- got singleton ---------------' + this.isa);
461                 //if (this.isa == "CONSTRUCTOR") {
462                 //      this.isNamespace = true;
463                 //}
464             }
465             
466             
467             
468             // @inner
469             if (this.comment.getTag(DocTagTitle.INNER).size > 0) {
470                 this.isInner = true;
471                 this.isStatic = false;
472             }
473             
474             
475             // @field
476             if (this.comment.getTag(DocTagTitle.FIELD).size > 0) {
477                 this.isa = "OBJECT";
478             }
479             
480            
481             
482             // @function
483             if (this.comment.getTag(DocTagTitle.FUNCTION).size > 0) {
484                 this.isa = "FUNCTION";
485             }
486             
487             // @param
488             if (this.comment.getTag(DocTagTitle.PARAM).size > 0 && this.isa == "OBJECT" ) {
489                 // change a property to a function..
490                 this.isa = "FUNCTION";
491             }
492             
493             
494              
495             
496             // @event
497             var events = this.comment.getTag(DocTagTitle.EVENT);
498             if (events.size > 0) {
499                 this.isa = "FUNCTION";
500                 this.isEvent = true;
501             }
502             
503             
504             
505             // @name
506             var names = this.comment.getTag(DocTagTitle.NAME);
507             if (names.size > 0) {
508                 this.private_name = names.get(0).desc.strip();
509             }
510             
511             /*~t
512                 // todo
513             */
514             
515             // @property
516             var properties = this.comment.getTag(DocTagTitle.PROPERTY);
517             if (properties.size > 0) {
518                 //var thisProperties = this.properties;
519                 for (var i = 0; i < properties.size; i++) {
520
521                                         
522                                         // if the doc tag just says @property ... but no name etc..
523                                         // then name will not be filled in..
524                                         if (properties[i].name.length < 1 ) {
525                                                 continue;
526                                         }
527
528                     var property = new Symbol.new_populate_with_args(
529                         this.alias+"#"+properties[i].name,
530                          new Gee.ArrayList<string>(), 
531                         "OBJECT",
532                          new DocComment(
533                             "/**\n"+
534                                 properties[i].desc+
535                                 "\n@name "+ properties[i].name
536                                 +"\n@memberOf "+this.alias+"#*/"
537                     ));
538                     // TODO: shouldn't the following happen in the addProperty method of Symbol?
539                     property.private_name = properties[i].name;
540                     property.memberOf = this.alias;
541                     if (properties[i].type.length > 0) property.type = properties[i].type;
542                     if (properties[i].defaultValue.length > 0) property.defaultValue = properties[i].defaultValue;
543                     this.addProperty(property);
544                     JSDOC.DocParser.addSymbol(property);
545                 }
546             }
547             
548             // config..
549             var conf = this.comment.getTag(DocTagTitle.CFG);
550             if (conf.size > 0) {
551                 for (var i = 0; i < conf.size; i++) {
552                     this.addConfig(conf.get(i));
553                 }
554             }
555             
556           
557
558             // @return
559             var returns = this.comment.getTag(DocTagTitle.RETURN);
560             if (returns.size > 0) { // there can be many return tags in a single doclet
561                 this.returns = returns;
562
563                 this.type = "";
564                 foreach(var r in returns) {
565                     this.type += this.type == "" ? "": ", ";
566                     this.type += r.type;
567                 } 
568              }
569             
570             
571             
572             // @exception
573             this.exceptions = this.comment.getTag(DocTagTitle.THROWS);
574             
575            
576             // @requires
577             var requires = this.comment.getTag(DocTagTitle.REQUIRES);
578             if (requires.size > 0) {
579                 this.requires = new Gee.ArrayList<string>();
580                 foreach(var r in requires) {
581                     this.requires.add(r.desc);
582                 }
583             }
584            
585             
586             // @type
587             var types = this.comment.getTag(DocTagTitle.TYPE);
588             if (types.size > 0) {
589                 this.type = types.get(0).desc; //multiple type tags are ignored
590             }
591             
592             
593             
594             // @private
595             if (this.comment.getTag(DocTagTitle.PRIVATE).size > 0 || this.isInner) {
596                 this.isPrivate = true;
597             }
598             
599             // @ignore
600             if (this.comment.getTag(DocTagTitle.IGNORE).size > 0) {
601                 this.isIgnored = true;
602             }
603             
604             /*~t
605                 // todo
606             */
607             
608             // @inherits ... as ... -- not used!!!
609             /*
610             var inherits = this.comment.getTag("inherits");
611             if (inherits.length) {
612                 for (var i = 0; i < inherits.length; i++) {
613                     if (/^\s*([a-z$0-9_.#-]+)(?:\s+as\s+([a-z$0-9_.#]+))?/i.test(inherits[i].desc)) {
614                         var inAlias = RegExp.$1;
615                         var inAs = RegExp.$2 || inAlias;
616
617                         if (inAlias) inAlias = inAlias.replace(/\.prototype\.?/g, "#");
618                         
619                         if (inAs) {
620                             inAs = inAs.replace(/\.prototype\.?/g, "#");
621                             inAs = inAs.replace(/^this\.?/, "#");
622                         }
623
624                         if (inAs.indexOf(inAlias) != 0) { //not a full namepath
625                             var joiner = ".";
626                             if (this.alias.charAt(this.alias.length-1) == "#" || inAs.charAt(0) == "#") {
627                                 joiner = "";
628                             }
629                             inAs = this.alias + joiner + inAs;
630                         }
631                     }
632                     this.inherits.push({alias: inAlias, as: inAs});
633                 }
634             }
635             */
636             /*~t
637                 // todo
638             */
639
640             // @augments
641             foreach(var dt in this.comment.getTag(DocTagTitle.ARGUMENTS)) {
642                 this.augments.add(dt.desc);
643                 }
644             //@extends - Ext            
645             foreach(var dt in this.comment.getTag(DocTagTitle.EXTENDS)) {
646                 this.augments.add(dt.desc);
647                 }
648             
649             
650             
651             // @default
652             var defaults = this.comment.getTag(DocTagTitle.DEFAULT);
653             if (defaults.size > 0) {
654                 if (this.is("OBJECT")) {
655                     this.defaultValue = defaults.get(0).desc;
656                 }
657             }
658             
659             /*~t
660                 // todo
661             */
662             
663             // @memberOf
664             var memberOfs = this.comment.getTag(DocTagTitle.MEMBEROF);
665             if (memberOfs.size > 0) {
666                 this.memberOf = memberOfs[0].desc;
667                 var pr_reg = /\.prototype\.?/;
668                 
669                 this.memberOf = pr_reg.replace(this.memberOf, this.memberOf.length, 0, "#");
670                 var dname = this.name.split(".");
671                 var name = dname[dname.length-1];
672                 
673                 var hname = name.split("#");
674                 name = hname[hname.length-1];
675                 this.private_name = this.memberOf + "." + name; //?? "." ???
676                 this.alias = this.name;
677             }
678
679             /*~t
680                 // todo
681             */
682              
683             // @public
684             if (this.comment.getTag(DocTagTitle.PUBLIC).size > 0) {
685                 this.isPrivate = false;
686             }
687             
688             /*~t
689                 // todo
690             */
691         }
692
693         public bool is (string what) {
694             return this.isa == what;
695         }
696         public bool isaClass()
697         {
698         
699                 return (this.is("CONSTRUCTOR") || this.isNamespace ); //|| this.isClass); 
700         }
701         
702  
703         public bool isBuiltin() {
704             return SymbolSet.isBuiltin(this.alias);
705         }
706
707         void setType(string comment,bool overwrite) {
708             if (!overwrite && this.type.length > 0) {
709                  return;
710                  }
711             var typeComment = DocComment.unwrapComment(comment);
712             this.type = typeComment;
713         }
714
715         public void inherit (Symbol symbol) {
716             if (!this.hasMember(symbol.name) && !symbol.isInner) {
717                 if (symbol.is("FUNCTION"))
718                     this.methods.add(symbol);
719                 else if (symbol.is("OBJECT"))
720                     this.properties.add(symbol);
721             }
722         }
723
724         bool hasMember (string name) {
725             return (this.hasMethod(name) || this.hasProperty(name));
726         }
727
728         public void addMember (Symbol symbol) {
729             //println("ADDMEMBER: " + this.name +  " ++ " + symbol.name);
730             
731             if (symbol.comment.getTag(DocTagTitle.CFG).size == 1) { 
732                 symbol.comment.getTag(DocTagTitle.CFG).get(0).memberOf = this.alias;
733                 this.addConfig(symbol.comment.getTag(DocTagTitle.CFG).get(0));
734                 return;
735             }
736             
737             if (symbol.is("FUNCTION")) { this.addMethod(symbol); }
738             else if (symbol.is("OBJECT")) { this.addProperty(symbol); }
739         }
740
741         bool hasMethod (string name) {
742             var thisMethods = this.methods;
743             for (var i = 0, l = thisMethods.size; i < l; i++) {
744                 if (thisMethods.get(i).name == name) return true;
745                 if (thisMethods.get(i).alias == name) return true;
746             }
747             return false;
748         }
749
750         void addMethod (Symbol symbol) {
751             var methodAlias = symbol.alias;
752             var thisMethods = this.methods;
753             for (var i = 0, l = thisMethods.size; i < l; i++) {
754                 if (thisMethods.get(i).alias == methodAlias) {
755                     thisMethods.set(i, symbol); // overwriting previous method
756                     return;
757                 }
758             }
759             thisMethods.add(symbol); // new method with this alias
760         }
761
762         bool hasProperty(string name) {
763             var thisProperties = this.properties;
764             for (var i = 0, l = thisProperties.size; i < l; i++) {
765                 if (thisProperties.get(i).name == name) return true;
766                 if (thisProperties.get(i).alias == name) return true;
767             }
768             return false;
769         }
770
771         void addProperty(Symbol symbol) {
772             var propertyAlias = symbol.alias;
773             var thisProperties = this.properties;
774             for (var i = 0, l = thisProperties.size; i < l; i++) {
775                 if (thisProperties.get(i).alias == propertyAlias) {
776                     thisProperties.set(i, symbol); // overwriting previous property
777                     return;
778                 }
779             }
780
781             thisProperties.add(symbol); // new property with this alias
782         }
783         
784         public void addDocTag(DocTag docTag)
785         {
786             this.comment.tags.add(docTag);
787             if (docTag.title == DocTagTitle.CFG) {
788                 this.addConfig(docTag);
789             }
790              
791         }
792         
793         public void addConfig(DocTag docTag)
794         {
795             if (docTag.memberOf == "") {
796                 // remove prototype data...
797                 //var a = this.alias.split('#')[0];
798                 //docTag.memberOf = a;
799                 docTag.memberOf = this.alias;
800             }
801             if (!this.cfgs.has_key(docTag.name)) {
802                 this.cfgs.set(docTag.name,  docTag);
803             }
804             
805         }
806          
807         public Gee.ArrayList<DocTag> configToArray()
808         {
809             var r = new  Gee.ArrayList<DocTag>();
810             foreach(var ci in this.cfgs.keys) {
811                 // dont show hidden!!
812                 if (this.cfgs.get(ci).desc.contains("@hide")) {
813                     continue;
814                 }
815                 r.add(this.cfgs.get(ci)); 
816                
817             }
818             return r;
819         }
820         
821         
822                 
823                 public string makeFuncSkel() {
824                     if (this.params.size < 1) return "function ()\n{\n\n}";
825                         var ret = "function (";
826                         var f = false;
827                         foreach(var p in this.params) {
828                                 if (p.name.contains(".")) continue;
829                                 ret += f ? ", " : "";
830                                 f = true;
831                                 ret +=  p.name == "this" ? "_self" : p.name;
832                         }
833                         return ret + ")\n{\n\n}";
834                 }
835                 public string makeMethodSkel() {
836                     if (this.params.size < 1) return "()\n{\n\n}";
837                         var ret = "(";
838                         var f = false;
839                         foreach(var p in this.params) {
840                                 GLib.debug("got param: %s", p.asString());
841                                 if (p.name.contains(".")) continue;
842                                 ret += f ? ", " : "";
843                                 f = true;
844                                 switch(p.name) {
845                                         case "this" : ret += "this"; break;
846                                         case "function" : ret += "function() {\n\n}"; break;                                    
847                                         default : ret += p.name; break;
848                                 }
849                         }
850                         return ret + ")";
851                 }
852                 
853                 public Json.Array paramsToJson()
854                 {
855                         var ret = new Json.Array();
856                         foreach(var p in this.params) {
857                                 //GLib.debug("got param: %s", p.asString());
858                                 if (p.name.contains(".")) continue;// ?? why?                           
859                                 var add = new Json.Object();
860                                 add.set_string_member("name",p.name);                           
861                                 add.set_string_member("type",p.type);
862                                 add.set_string_member("desc",p.desc);
863                                 add.set_boolean_member("isOptional",p.isOptional);
864                                 ret.add_object_element(add) ;
865                         }
866                          
867                         return ret;
868                 
869                 }
870         public Json.Array returnsToJson()
871                 {
872                         var ret = new Json.Array();
873                         foreach(var p in this.returns) {
874                                 //GLib.debug("got param: %s", p.asString());
875                                 if (p.name.contains(".")) continue;// ?? why?                           
876                                 var add = new Json.Object();
877                                 add.set_string_member("name",p.name);                           
878                                 add.set_string_member("type",p.type);
879                                 add.set_string_member("desc",p.desc);
880                  
881                                 ret.add_object_element(add) ;
882                         }
883                          
884                         return ret;
885                 
886                 }
887                 public Json.Array stringArrayToJson( Gee.ArrayList<string> ar) 
888                 {
889                         var ret = new Json.Array();
890                         foreach(var a in ar) {
891                                 ret.add_string_element(a);
892                         }
893                         return ret;
894                 
895                 }
896                 public Json.Array symbolArrayToJson( Gee.ArrayList<Symbol> ar) 
897                 {
898                         var ret = new Json.Array();
899                         foreach(var a in ar) {
900                                 ret.add_object_element(a.toJson());
901                         }
902                         return ret;
903                 
904                 }
905                 public Json.Array docTagsArrayToJson( Gee.ArrayList<DocTag> ar) 
906                 {
907                         var ret = new Json.Array();
908                         foreach(var a in ar) {
909                                 ret.add_object_element(a.toJson());
910                         }
911                         return ret;
912                 
913                 } 
914                 
915                 
916                 
917                 public Json.Object assocDocTagToJson( Gee.HashMap<string,DocTag> ar) 
918                 {
919                         var ret = new Json.Object();
920                         foreach(var a in ar.keys) {
921                                 ret.set_object_member(a, ar.get(a).toJson());
922                         }
923                         return ret;
924                 
925                 } 
926                 
927                 
928                 public Json.Object toJson()
929                 {
930                         var ret = new Json.Object();
931                         ret.set_string_member("name", this.name);
932                         ret.set_array_member("params", this.docTagsArrayToJson(this.params));
933
934                         ret.set_array_member("augments", this.stringArrayToJson(this.augments));
935                         ret.set_array_member("exceptions", this.docTagsArrayToJson(this.exceptions));
936                         ret.set_array_member("methods", this.symbolArrayToJson(this.methods));
937                         ret.set_array_member("properties", this.symbolArrayToJson(this.properties));
938                         ret.set_array_member("requires", this.stringArrayToJson(this.requires));
939                         ret.set_array_member("returns", this.docTagsArrayToJson(this.returns));
940                         ret.set_array_member("see", this.stringArrayToJson(this.see));
941                         ret.set_array_member("childClasses", this.stringArrayToJson(this.childClasses));
942                         ret.set_array_member("inheritsFrom", this.stringArrayToJson(this.inheritsFrom));
943                         ret.set_object_member("cfgs", this.assocDocTagToJson(this.cfgs));
944                         ret.set_object_member("comment", this.comment.toJson());
945                       //$args : [], // original arguments used when constructing.
946  
947                         ret.set_string_member("alias", this.alias);
948         
949                         ret.set_string_member("author", this.author);
950                         ret.set_string_member("classDesc" , this.classDesc);
951                         ret.set_string_member("deprecated", this.deprecated);
952                         ret.set_string_member("desc", this.desc);
953                         //events : false,
954                         ret.set_string_member("example", this.example);
955                         
956                         ret.set_string_member("isa", this.isa);
957
958                         ret.set_boolean_member("isEvent", this.isEvent);
959                         ret.set_boolean_member("isConstant", this.isConstant);
960                         ret.set_boolean_member("isIgnored", this.isIgnored);
961                         ret.set_boolean_member("isInner", this.isInner);
962                         ret.set_boolean_member("isNamespace", this.isNamespace);
963                         ret.set_boolean_member("isPrivate", this.isPrivate);
964                         ret.set_boolean_member("isStatic", this.isStatic);
965  
966                         ret.set_string_member("memberOf", this.memberOf);
967                         return ret;
968                 }
969                 
970                 
971                 
972                 
973                 
974                 
975                 
976                 
977                 
978                 
979         }
980  
981         
982         
983         //static string[] hide = { "$args" };
984         //static string srcFile = "";
985          
986 }
987
988
989 /*
990 Symbol.fromDump = function(t)
991 {
992     var ns = new Symbol();
993     for (var i in t) {
994         if (typeof(ns[i]) == "undefined") {
995             println("ERR:no default for Symbol:"+ i);
996         }
997         ns[i] = t[i];
998     }
999     return ns;
1000 }
1001 */