Uncommited changes synced
[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.HashMap<string,Gee.ArrayList<string>> childClasses;
100                 public Gee.ArrayList<string> childClassesList;
101                 public Gee.ArrayList<string> inheritsFrom;
102                 public Gee.HashMap<string,DocTag>cfgs;
103
104
105                 public Gee.ArrayList<string> tree_parent;
106                 public Gee.ArrayList<string> tree_children;
107                 
108
109         public DocComment comment;
110                 
111         //$args : [], // original arguments used when constructing.
112         //string addOn = "";
113         public string alias = "";
114         
115         string author = "";
116         string classDesc = "";
117
118         string deprecated = "";
119         public string desc = "";
120         //events : false,
121         string example = "";
122         
123
124                 public string isa = "OBJECT"; // OBJECT//FUNCTION
125         
126                 public bool isEvent = false;
127                 public bool isConstant = false;
128                 public bool isIgnored = false;
129                 public bool isInner = false;
130                 public bool isNamespace = false;
131                 public bool isPrivate = false;
132                 public bool isStatic = false;
133                 public bool isAbstract = false;
134                 public bool isBuilderTop = false;
135         
136         public string memberOf = "";
137
138                 public string asString()
139                 {
140                         return "NAME: %s:%s   ASNAME: %s : %s%s%s%s".printf(
141                                 this.memberOf,
142                                 this.name,
143                                 this._assigned_name,
144                                 isStatic ? "static": "",
145                                 isEvent ? "EV": "",
146                                 isConstant ? "CO": "",
147                                 isNamespace ? "NS": ""
148                         );
149                                 
150                 
151                 }
152
153        
154         string since = "";
155
156         string type = "";
157         string version = "";
158        
159         public static string srcFile = "";
160         
161         
162         
163         public void initArrays()
164         {
165             // only initialize arrays / objects..
166
167             
168             //this.params = [];
169             //this.$args = [];
170             
171             //this.events = [];
172             this.exceptions = new Gee.ArrayList<DocTag>();
173             //this.inherits = new Gee.ArrayList<DocTag>();
174             //
175             this.isa = "OBJECT"; // OBJECT//FUNCTION
176             this.methods = new Gee.ArrayList<Symbol>();
177             //this.private_params = new Gee.ArrayList<DocTag>();
178             this.properties = new Gee.ArrayList<Symbol>();
179             this.requires = new Gee.ArrayList<string>();
180             this.returns = new Gee.ArrayList<DocTag>();
181             this.see = new Gee.ArrayList<string>();
182             this.augments = new Gee.ArrayList<string>();
183  
184             
185             this.cfgs = new Gee.HashMap<string,DocTag>();
186             // what is this?
187             this.inheritsFrom = new Gee.ArrayList<string>();
188
189             this.childClasses = new Gee.HashMap<string,Gee.ArrayList<string>>();
190             this.childClassesList = new Gee.ArrayList<string>();
191             
192             this.tree_parent = new Gee.ArrayList<string>();
193             this.tree_children = new Gee.ArrayList<string>();
194             
195              
196             this.comment = new DocComment();
197             this.comment.isUserComment =  false;
198             
199                
200         }
201                 
202                 public Symbol.new_builtin(string name)
203                 {
204             
205             this.initArrays();
206             this.srcFile = JSDOC.DocParser.currentSourceFile;
207                         this.private_name =  name ;
208                         this.alias = this.name;
209                         this.isa = "CONSTRUCTOR";
210                         this.comment = new DocComment("");
211                         this.comment.isUserComment =  false;
212                         this.isNamespace = false;
213                         this.srcFile = "";
214                         this.isPrivate = false;
215                         // init arrays....
216                         
217                         
218                         
219                 }
220                 
221
222  
223
224         public Symbol.new_populate_with_args(
225                 string  name,
226                 Gee.ArrayList<string> params, // fixme???
227                 string isa,
228                 DocComment comment
229         ) {
230            
231             this.initArrays();
232            // this.$args = arguments;
233             //println("Symbol created: " + isa + ":" + name);
234             this.private_name = name;
235             this.alias = this.name;
236             this.private_string_params = params; 
237             this.isa = (isa == "VIRTUAL")? "OBJECT":isa;
238             this.comment =  comment;
239             
240             this.srcFile = DocParser.currentSourceFile;
241             
242            
243             
244             if (this.is("FILE") && this.alias.length < 1) { // this will never hapen???
245                         this.alias = this.srcFile;
246                 }
247
248             this.tagsFromComment();
249             
250         }
251
252         void tagsFromComment() 
253         {
254             // @author
255             var authors = this.comment.getTag(DocTagTitle.AUTHOR);
256             if (authors.size > 0) {
257                         // turns author into a string....
258                         this.author = "";
259                 foreach(var a in authors) {
260                     this.author += (this.author == "") ? "": ", ";
261                     this.author += a.desc;
262                 }
263             }
264             
265             /*~t
266                 assert("testing Symbol");
267                 
268                 requires("../lib/JSDOC/DocComment.js");
269                 requires("../frame/String.js");
270                 requires("../lib/JSDOC/DocTag.js");
271
272                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@author Joe Smith*"+"/"));
273                 assertEqual(sym.author, "Joe Smith", "@author tag, author is found.");
274             */
275             // @desc
276             var mth = this.comment.getTag(DocTagTitle.METHOD);
277             if (mth.size  > 0) {
278                 this.isa = "FUNCTION";
279             }
280             // @desc
281             var descs = this.comment.getTag(DocTagTitle.DESC);
282             if (descs.size>  0) {
283                 this.desc = "";
284                 foreach(var d in descs) {
285                     this.desc = this.desc == "" ? "": "\n";
286                     this.desc += d.desc;
287                 }
288
289             }
290             
291             /*~t
292                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@desc This is a description.*"+"/"));
293                 assertEqual(sym.desc, "This is a description.", "@desc tag, description is found.");
294             */
295             
296             // @overview
297             if (this.is("FILE")) {
298                 if (this.alias.length < 1) this.alias = this.srcFile;
299                 
300                 var overviews = this.comment.getTag(DocTagTitle.OVERVIEW);
301                 if (overviews.size > 0) {
302                     foreach(var d in overviews) {
303                         this.desc = this.desc == "" ? "": "\n";
304                         this.desc += d.desc;
305                     }
306                 }
307             }
308             
309             /*~t
310                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@overview This is an overview.*"+"/"));
311                 assertEqual(sym.desc, "\nThis is an overview.", "@overview tag, description is found.");
312             */
313             
314             // @since
315             var sinces = this.comment.getTag(DocTagTitle.SINCE);
316             if (sinces.size > 0) {
317                 this.since = "";
318                 foreach(var d in sinces) {
319                     this.since = this.since == "" ? "": "\n";
320                     this.since += d.desc;
321                 }
322             }
323             
324             /*~t
325                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@since 1.01*"+"/"));
326                 assertEqual(sym.since, "1.01", "@since tag, description is found.");
327             */
328             
329             // @constant
330             if (this.comment.getTag(DocTagTitle.CONSTANT).size > 0) {
331                 this.isConstant = true;
332                 this.isa = "OBJECT";
333             }
334             
335             /*~t
336                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@constant*"+"/"));
337                 assertEqual(sym.isConstant, true, "@constant tag, isConstant set.");
338             */
339             
340             // @version
341             var versions = this.comment.getTag(DocTagTitle.VERSION);
342             if (versions.size > 0 ) {
343                 this.version = "";
344                  foreach(var d in versions) {
345                     this.version = this.version == "" ? "": "\n";
346                     this.version += d.desc;
347                 }
348             }
349             
350             /*~t
351                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@version 2.0x*"+"/"));
352                 assertEqual(sym.version, "2.0x", "@version tag, version is found.");
353             */
354             
355             // @deprecated
356             var deprecateds = this.comment.getTag(DocTagTitle.DEPRECATED);
357             if (deprecateds.size > 0) {
358                 this.deprecated = "";
359                  foreach(var d in deprecateds) {
360                     this.deprecated = this.deprecated == "" ? "": "\n";
361                     this.deprecated += d.desc;
362                 }
363             }
364             
365             /*~t
366                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@deprecated Use other method.*"+"/"));
367                 assertEqual(sym.deprecated, "Use other method.", "@deprecated tag, desc is found.");
368             */
369             
370             // @example
371             var examples = this.comment.getTag(DocTagTitle.EXAMPLE);
372             if (examples.size > 0) {
373                 this.example = examples.get(0).desc;
374             }
375             
376             /*~t
377                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@example This\n  is an example.*"+"/"));
378                 assertEqual(sym.example, "This\n  is an example.", "@deprecated tag, desc is found.");
379             */
380             
381             // @see
382             var sees = this.comment.getTag(DocTagTitle.SEE);
383             if (sees.size > 0) {
384                  
385                 foreach(var s in sees) {
386                     this.see.add(s.desc);
387                 }
388           }
389             
390             /*~t
391                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@see The other thing.*"+"/"));
392                 assertEqual(sym.see, "The other thing.", "@see tag, desc is found.");
393             */
394             
395             // @class
396             var classes = this.comment.getTag(DocTagTitle.CLASS);
397             if (classes.size > 0) {
398                 //print(JSON.stringify(this,null,4));
399                 this.isa = "CONSTRUCTOR";
400                 this.classDesc = classes[0].desc; // desc can't apply to the constructor as there is none.
401                 //if (!this.classDesc.leg) {
402                 //    this.classDesc = this.desc;
403                 //   }
404                 
405                 
406             }
407             
408             /*~t
409                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@class This describes the class.*"+"/"));
410                 assertEqual(sym.isa, "CONSTRUCTOR", "@class tag, makes symbol a constructor.");
411                 assertEqual(sym.classDesc, "This describes the class.", "@class tag, class description is found.");
412             */
413             
414             // @namespace
415             var namespaces = this.comment.getTag(DocTagTitle.NAMESPACE);
416             if (namespaces.size > 0) {
417                 this.classDesc = namespaces[0].desc+"\n"+this.desc; // desc can't apply to the constructor as there is none.
418                 this.isNamespace = true;
419             }
420             
421             /*~t
422                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@namespace This describes the namespace.*"+"/"));
423                 assertEqual(sym.classDesc, "This describes the namespace.\n", "@namespace tag, class description is found.");
424             */
425             
426             // @param
427             var params = this.comment.getTag(DocTagTitle.PARAM);
428             if (params.size > 0) {
429                 // user-defined params overwrite those with same name defined by the parser
430                 var thisParams = params;
431
432                 if (thisParams.size == 0) { // none exist yet, so just bung all these user-defined params straight in
433                     this.private_params = params;
434                 }
435                 else { // need to overlay these user-defined params on to existing parser-defined params
436                     for (var i = 0, l = params.size; i < l; i++) {
437                         if (thisParams.size <= i) {
438                                 var np = thisParams.get(i);
439                                 
440                             if (np.type.length > 0) np.type = params[i].type;
441                             np.name = params[i].name;
442                             np.desc = params[i].desc;
443                             np.isOptional = params[i].isOptional;
444                             np.defaultValue = params[i].defaultValue;
445                             //thisParams.set(i, np); ///?? needed OO ?
446                         }
447                         else thisParams.set(i, params[i]);
448                     }
449                     this.private_params = thisParams;
450                 }
451             }
452             
453             
454             
455             // @constructor
456             if (this.comment.getTag(DocTagTitle.CONSTRUCTOR).size > 0) {
457                 this.isa = "CONSTRUCTOR";
458             }
459             
460          
461             
462             // @static
463             if (this.comment.getTag(DocTagTitle.STATIC).size > 0) {
464                 GLib.debug("set class %s to static (static)", this.alias);
465                 this.isStatic = true;
466                 if (this.isa == "CONSTRUCTOR") {
467                     this.isNamespace = true;
468                 }
469             }
470             
471             // @singleton - technically it's an arready instanticsed class - eg. Roo.Ajax == new Roo.util.Connection
472             if (this.comment.getTag(DocTagTitle.SINGLETON).size > 0) {
473                 GLib.debug("set class %s to static (singleton)", this.alias);
474                 this.isStatic = true;
475                 //print('------------- got singleton ---------------' + this.isa);
476                 //if (this.isa == "CONSTRUCTOR") {
477                 //      this.isNamespace = true;
478                 //}
479             }
480             
481             
482             
483             // @inner
484             if (this.comment.getTag(DocTagTitle.INNER).size > 0) {
485                 this.isInner = true;
486                 this.isStatic = false;
487             }
488             
489             
490             // @field
491             if (this.comment.getTag(DocTagTitle.FIELD).size > 0) {
492                 this.isa = "OBJECT";
493             }
494             
495            
496             
497             // @function
498             if (this.comment.getTag(DocTagTitle.FUNCTION).size > 0) {
499                 this.isa = "FUNCTION";
500             }
501             
502             // @param
503             if (this.comment.getTag(DocTagTitle.PARAM).size > 0 && this.isa == "OBJECT" ) {
504                 // change a property to a function..
505                 this.isa = "FUNCTION";
506             }
507             
508             
509              
510             
511             // @event
512             var events = this.comment.getTag(DocTagTitle.EVENT);
513             if (events.size > 0) {
514                 this.isa = "FUNCTION";
515                 this.isEvent = true;
516             }
517             
518             
519             
520             // @name
521             var names = this.comment.getTag(DocTagTitle.NAME);
522             if (names.size > 0) {
523                 this.private_name = names.get(0).desc.strip();
524             }
525             
526             /*~t
527                 // todo
528             */
529             
530             // @property
531             var properties = this.comment.getTag(DocTagTitle.PROPERTY);
532             if (properties.size > 0) {
533                 //var thisProperties = this.properties;
534                 for (var i = 0; i < properties.size; i++) {
535
536                                         
537                                         // if the doc tag just says @property ... but no name etc..
538                                         // then name will not be filled in..
539                                         if (properties[i].name.length < 1 ) {
540                                                 continue;
541                                         }
542
543                     var property = new Symbol.new_populate_with_args(
544                         this.alias+"#"+properties[i].name,
545                          new Gee.ArrayList<string>(), 
546                         "OBJECT",
547                          new DocComment(
548                             "/**\n"+
549                                 properties[i].desc+
550                                 "\n@name "+ properties[i].name
551                                 +"\n@memberOf "+this.alias+"#*/"
552                     ));
553                     // TODO: shouldn't the following happen in the addProperty method of Symbol?
554                     property.private_name = properties[i].name;
555                     property.memberOf = this.alias;
556                     if (properties[i].type.length > 0) property.type = properties[i].type;
557                     if (properties[i].defaultValue.length > 0) property.defaultValue = properties[i].defaultValue;
558                     this.addProperty(property);
559                     JSDOC.DocParser.addSymbol(property);
560                 }
561             }
562             
563             // config..
564             var conf = this.comment.getTag(DocTagTitle.CFG);
565             if (conf.size > 0) {
566                 for (var i = 0; i < conf.size; i++) {
567                     this.addConfig(conf.get(i));
568                 }
569             }
570             
571           
572
573             // @return
574             var returns = this.comment.getTag(DocTagTitle.RETURN);
575             if (returns.size > 0) { // there can be many return tags in a single doclet
576                 this.returns = returns;
577
578                 this.type = "";
579                 foreach(var r in returns) {
580                     this.type += this.type == "" ? "": ", ";
581                     this.type += r.type;
582                 } 
583              }
584             
585             
586             
587             // @exception
588             this.exceptions = this.comment.getTag(DocTagTitle.THROWS);
589             
590            
591             // @requires
592             var requires = this.comment.getTag(DocTagTitle.REQUIRES);
593             if (requires.size > 0) {
594                 this.requires = new Gee.ArrayList<string>();
595                 foreach(var r in requires) {
596                     this.requires.add(r.desc);
597                 }
598             }
599            
600             
601             // @type
602             var types = this.comment.getTag(DocTagTitle.TYPE);
603             if (types.size > 0) {
604                 this.type = types.get(0).desc; //multiple type tags are ignored
605             }
606             
607             
608             
609             // @private
610             if (this.comment.getTag(DocTagTitle.PRIVATE).size > 0 || this.isInner) {
611                 this.isPrivate = true;
612             }
613             
614             // @ignore
615             if (this.comment.getTag(DocTagTitle.IGNORE).size > 0) {
616                 this.isIgnored = true;
617             }
618             
619             /*~t
620                 // todo
621             */
622             
623             // @inherits ... as ... -- not used!!!
624             /*
625             var inherits = this.comment.getTag("inherits");
626             if (inherits.length) {
627                 for (var i = 0; i < inherits.length; i++) {
628                     if (/^\s*([a-z$0-9_.#-]+)(?:\s+as\s+([a-z$0-9_.#]+))?/i.test(inherits[i].desc)) {
629                         var inAlias = RegExp.$1;
630                         var inAs = RegExp.$2 || inAlias;
631
632                         if (inAlias) inAlias = inAlias.replace(/\.prototype\.?/g, "#");
633                         
634                         if (inAs) {
635                             inAs = inAs.replace(/\.prototype\.?/g, "#");
636                             inAs = inAs.replace(/^this\.?/, "#");
637                         }
638
639                         if (inAs.indexOf(inAlias) != 0) { //not a full namepath
640                             var joiner = ".";
641                             if (this.alias.charAt(this.alias.length-1) == "#" || inAs.charAt(0) == "#") {
642                                 joiner = "";
643                             }
644                             inAs = this.alias + joiner + inAs;
645                         }
646                     }
647                     this.inherits.push({alias: inAlias, as: inAs});
648                 }
649             }
650             */
651             /*~t
652                 // todo
653             */
654
655             // @augments
656             foreach(var dt in this.comment.getTag(DocTagTitle.ARGUMENTS)) {
657                 this.augments.add(dt.desc);
658                 }
659             //@extends - Ext            
660             foreach(var dt in this.comment.getTag(DocTagTitle.EXTENDS)) {
661                 this.augments.add(dt.desc);
662                 }
663             
664             
665             
666             // @default
667             var defaults = this.comment.getTag(DocTagTitle.DEFAULT);
668             if (defaults.size > 0) {
669                 if (this.is("OBJECT")) {
670                     this.defaultValue = defaults.get(0).desc;
671                 }
672             }
673             
674             /*~t
675                 // todo
676             */
677             
678             // @memberOf
679             var memberOfs = this.comment.getTag(DocTagTitle.MEMBEROF);
680             if (memberOfs.size > 0) {
681                 this.memberOf = memberOfs[0].desc;
682                 var pr_reg = /\.prototype\.?/;
683                 
684                 this.memberOf = pr_reg.replace(this.memberOf, this.memberOf.length, 0, "#");
685                 var dname = this.name.split(".");
686                 var name = dname[dname.length-1];
687                 
688                 var hname = name.split("#");
689                 name = hname[hname.length-1];
690                 this.private_name = this.memberOf + "." + name; //?? "." ???
691                 this.alias = this.name;
692             }
693
694            
695              
696             // @public
697             if (this.comment.getTag(DocTagTitle.PUBLIC).size > 0) {
698                 this.isPrivate = false;
699             }
700              
701             // @children
702              if (this.comment.getTag(DocTagTitle.CHILDREN).size > 0) {
703                 foreach(var s in this.comment.getTag(DocTagTitle.CHILDREN).get(0).desc.strip().split(" ")) {
704                         this.tree_children.add(s);
705                 }
706             }
707             // @parent
708              if (this.comment.getTag(DocTagTitle.PARENT).size > 0) {
709                 foreach(var s in this.comment.getTag(DocTagTitle.PARENT).get(0).desc.strip().split(" ")) {
710                         this.tree_parent.add(s);
711                 }
712             }
713                         
714             // @abstract
715             if (this.comment.getTag(DocTagTitle.ABSTRACT).size > 0) {
716                 this.isAbstract = true;
717             }
718                         // @builder-top            
719                         if (this.comment.getTag(DocTagTitle.BUILDER_TOP).size > 0) {
720                 this.isBuilderTop = true;
721             }
722             
723             
724             
725              
726         }
727
728         public bool is (string what) {
729             return this.isa == what;
730         }
731         public bool isaClass()
732         {
733         
734                 return (this.is("CONSTRUCTOR") || this.isNamespace ); //|| this.isClass); 
735         }
736         
737  
738         public bool isBuiltin() {
739             return SymbolSet.isBuiltin(this.alias);
740         }
741
742         void setType(string comment,bool overwrite) {
743             if (!overwrite && this.type.length > 0) {
744                  return;
745                  }
746             var typeComment = DocComment.unwrapComment(comment);
747             this.type = typeComment;
748         }
749
750         public void inherit (Symbol symbol) {
751             if (!this.hasMember(symbol.name) && !symbol.isInner) {
752                 if (symbol.is("FUNCTION"))
753                     this.methods.add(symbol);
754                 else if (symbol.is("OBJECT"))
755                     this.properties.add(symbol);
756             }
757         }
758
759         bool hasMember (string name) {
760             return (this.hasMethod(name) || this.hasProperty(name));
761         }
762
763         public void addMember (Symbol symbol) {
764             //println("ADDMEMBER: " + this.name +  " ++ " + symbol.name);
765             
766             if (symbol.comment.getTag(DocTagTitle.CFG).size == 1) { 
767                 symbol.comment.getTag(DocTagTitle.CFG).get(0).memberOf = this.alias;
768                 this.addConfig(symbol.comment.getTag(DocTagTitle.CFG).get(0));
769                 return;
770             }
771             
772             if (symbol.is("FUNCTION")) { this.addMethod(symbol); }
773             else if (symbol.is("OBJECT")) { this.addProperty(symbol); }
774         }
775
776         bool hasMethod (string name) {
777             var thisMethods = this.methods;
778             for (var i = 0, l = thisMethods.size; i < l; i++) {
779                 if (thisMethods.get(i).name == name) return true;
780                 if (thisMethods.get(i).alias == name) return true;
781             }
782             return false;
783         }
784
785         void addMethod (Symbol symbol) {
786             var methodAlias = symbol.alias;
787             var thisMethods = this.methods;
788             for (var i = 0, l = thisMethods.size; i < l; i++) {
789                 if (thisMethods.get(i).alias == methodAlias) {
790                     thisMethods.set(i, symbol); // overwriting previous method
791                     return;
792                 }
793             }
794             thisMethods.add(symbol); // new method with this alias
795         }
796
797         bool hasProperty(string name) {
798             var thisProperties = this.properties;
799             for (var i = 0, l = thisProperties.size; i < l; i++) {
800                 if (thisProperties.get(i).name == name) return true;
801                 if (thisProperties.get(i).alias == name) return true;
802             }
803             return false;
804         }
805
806         void addProperty(Symbol symbol) {
807             var propertyAlias = symbol.alias;
808             var thisProperties = this.properties;
809             for (var i = 0, l = thisProperties.size; i < l; i++) {
810                 if (thisProperties.get(i).alias == propertyAlias) {
811                     thisProperties.set(i, symbol); // overwriting previous property
812                     return;
813                 }
814             }
815
816             thisProperties.add(symbol); // new property with this alias
817         }
818         
819         public void addChildClass(string clsname, string parent) 
820         {
821                 if (!this.childClasses.has_key( parent)) {
822                         this.childClasses.set(parent, new Gee.ArrayList<string>());
823                 }
824                 this.childClasses.get(parent).add(clsname);
825                 this.childClassesList.add(clsname);
826         }
827          
828         
829         public void addDocTag(DocTag docTag)
830         {
831             this.comment.tags.add(docTag);
832             if (docTag.title == DocTagTitle.CFG) {
833                 this.addConfig(docTag);
834             }
835              
836         }
837         
838         public void addConfig(DocTag docTag)
839         {
840             if (docTag.memberOf == "") {
841                 // remove prototype data...
842                 //var a = this.alias.split('#')[0];
843                 //docTag.memberOf = a;
844                 docTag.memberOf = this.alias;
845             }
846             if (!this.cfgs.has_key(docTag.name)) {
847                 this.cfgs.set(docTag.name,  docTag);
848             }
849             
850         }
851          
852         public Gee.ArrayList<DocTag> configToArray()
853         {
854             var r = new  Gee.ArrayList<DocTag>();
855             foreach(var ci in this.cfgs.keys) {
856                 // dont show hidden!!
857                 if (this.cfgs.get(ci).desc.contains("@hide")) {
858                     continue;
859                 }
860                 r.add(this.cfgs.get(ci)); 
861                
862             }
863             return r;
864         }
865         
866         
867                 
868                 public string makeFuncSkel() {
869                     if (this.params.size < 1) return "function ()\n{\n\n}";
870                         var ret = "function (";
871                         var f = false;
872                         foreach(var p in this.params) {
873                                 if (p.name.contains(".")) continue;
874                                 ret += f ? ", " : "";
875                                 f = true;
876                                 ret +=  p.name == "this" ? "_self" : p.name;
877                         }
878                         return ret + ")\n{\n\n}";
879                 }
880                 public string makeMethodSkel() {
881                     if (this.params.size < 1) return "()\n{\n\n}";
882                         var ret = "(";
883                         var f = false;
884                         foreach(var p in this.params) {
885                                 GLib.debug("got param: %s", p.asString());
886                                 if (p.name.contains(".")) continue;
887                                 ret += f ? ", " : "";
888                                 f = true;
889                                 switch(p.name) {
890                                         case "this" : ret += "this"; break;
891                                         case "function" : ret += "function() {\n\n}"; break;                                    
892                                         default : ret += p.name; break;
893                                 }
894                         }
895                         return ret + ")";
896                 }
897         
898                 public Json.Array stringArrayToJson( Gee.ArrayList<string> ar) 
899                 {
900                         var ret = new Json.Array();
901                         foreach(var a in ar) {
902                                 ret.add_string_element(a);
903                         }
904                         return ret;
905                 
906                 }
907                 public Json.Array symbolArrayToJson( Gee.ArrayList<Symbol> ar) 
908                 {
909                         var ret = new Json.Array();
910                         foreach(var a in ar) {
911                                 ret.add_object_element(a.toJson());
912                         }
913                         return ret;
914                 
915                 }
916                 public Json.Array docTagsArrayToJson( Gee.ArrayList<DocTag> ar) 
917                 {
918                         var ret = new Json.Array();
919                         foreach(var a in ar) {
920                                 ret.add_object_element(a.toJson());
921                         }
922                         return ret;
923                 
924                 } 
925                 
926                 public Json.Object assocStringToJson( Gee.HashMap<string,Gee.ArrayList<string>> ar) 
927                 {
928                         var ret = new Json.Object();
929                         foreach(var a in ar.keys) {
930                                 ret.set_array_member(a, this.stringArrayToJson(ar.get(a)));
931                         }
932                         return ret;
933                 
934                 } 
935                 
936                 public Json.Object assocDocTagToJson( Gee.HashMap<string,DocTag> ar) 
937                 {
938                         var ret = new Json.Object();
939                         foreach(var a in ar.keys) {
940                                 ret.set_object_member(a, ar.get(a).toJson());
941                         }
942                         return ret;
943                 
944                 } 
945                 
946                 /**
947                 * direct Json Dump
948                 */
949                 public Json.Object toJson()
950                 {
951                         var ret = new Json.Object();
952                         ret.set_string_member("name", this.name);
953                         ret.set_object_member("comment", this.comment.toJson()); //contains doctags?
954                         ret.set_boolean_member("isEvent", this.isEvent);
955                         ret.set_boolean_member("isConstant", this.isConstant);
956                         ret.set_boolean_member("isIgnored", this.isIgnored);
957                         ret.set_boolean_member("isInner", this.isInner);
958                         ret.set_boolean_member("isNamespace", this.isNamespace);
959                         ret.set_boolean_member("isPrivate", this.isPrivate);
960                         ret.set_boolean_member("isStatic", this.isStatic);
961                         ret.set_boolean_member("isAbstract", this.isAbstract);
962                         ret.set_boolean_member("isBuilderTop", this.isBuilderTop);      
963                         ret.set_string_member("memberOf", this.memberOf);
964                         ret.set_array_member("tree_children", this.stringArrayToJson(this.tree_children));
965                         ret.set_array_member("tree_parent", this.stringArrayToJson(this.tree_parent));
966                         
967                         
968                         ret.set_array_member("params", this.docTagsArrayToJson(this.params));
969
970                         ret.set_array_member("augments", this.stringArrayToJson(this.augments));
971                         ret.set_array_member("exceptions", this.docTagsArrayToJson(this.exceptions));
972                         ret.set_array_member("methods", this.symbolArrayToJson(this.methods));
973                         ret.set_array_member("properties", this.symbolArrayToJson(this.properties));
974                         ret.set_array_member("requires", this.stringArrayToJson(this.requires));
975                         ret.set_array_member("returns", this.docTagsArrayToJson(this.returns));
976                         ret.set_array_member("see", this.stringArrayToJson(this.see));
977                         ret.set_object_member("childClasses", this.assocStringToJson(this.childClasses));
978                         ret.set_array_member("inheritsFrom", this.stringArrayToJson(this.inheritsFrom));
979                         ret.set_object_member("cfgs", this.assocDocTagToJson(this.cfgs));
980
981                       //$args : [], // original arguments used when constructing.
982  
983                         ret.set_string_member("alias", this.alias);
984         
985                         ret.set_string_member("author", this.author);
986                         ret.set_string_member("classDesc" , this.classDesc);
987                         ret.set_string_member("deprecated", this.deprecated);
988                         ret.set_string_member("desc", this.desc);
989                         //events : false,
990                         ret.set_string_member("example", this.example);
991                         
992                         ret.set_string_member("isa", this.isa);
993
994
995
996                         return ret;
997                 }
998                 /**
999                 * This is the more detail Class output for documentation body text
1000                 */
1001                 
1002                 
1003                 public Json.Object toClassDocJSON ()
1004                 {
1005                         var ret = new Json.Object();
1006                         ret.set_string_member("name", this.alias);
1007                         
1008                         
1009                         var ag = new Json.Array();
1010                         ret.set_array_member("augments", this.stringArrayToJson(this.augments));
1011                         ret.set_object_member("childClasses", this.assocStringToJson(this.childClasses));
1012                         
1013                         ret.set_array_member("tree_children", this.stringArrayToJson(this.tree_children));
1014                         ret.set_array_member("tree_parent", this.stringArrayToJson(this.tree_parent));
1015
1016                         
1017                         ret.set_string_member("name", this.alias);  
1018                         ret.set_string_member("desc", this.desc);
1019                         ret.set_boolean_member("isSingleton", this.comment.getTag(DocTagTitle.SINGLETON).size > 0);
1020                         ret.set_boolean_member("isStatic", this.isStatic ); // ??? -> this.isa != "CONSTRUCTOR" ? true : this.isStatic);
1021                         ret.set_boolean_member("isBuiltin", this.isBuiltin());
1022                         ret.set_boolean_member("isAbstract", this.isAbstract);
1023                         ret.set_boolean_member("isBuilderTop", this.isBuilderTop);                      
1024
1025                         // needded so that the class can fake a ctor..
1026                         ret.set_string_member("memberOf", this.name);
1027                         ret.set_string_member("example", this.comment.getTagAsString(DocTagTitle.EXAMPLE));
1028                         ret.set_string_member("deprecated", // as depricated is used as a flag...
1029                                 this.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
1030                                 "This has been deprecated: "+  this.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
1031                         "");
1032                         ret.set_string_member("since", this.comment.getTagAsString(DocTagTitle.SINCE));
1033                         ret.set_string_member("see", this.comment.getTagAsString(DocTagTitle.SEE));
1034                         // ?? ctor? is that listed with the outer class?
1035                         
1036                         
1037                         
1038                         // this must be for the CTOR?
1039                         ret.set_array_member("params", this.paramsToJson());
1040                         ret.set_array_member("returns", new Json.Array()); // this is a placeholder - classes dont have returns..
1041                 ret.set_string_member("throws", this.comment.getTagAsString(DocTagTitle.THROWS));
1042                         ret.set_string_member("requires", this.comment.getTagAsString(DocTagTitle.REQUIRES));
1043                         
1044                         
1045                         var props = new Json.Array(); 
1046                         ret.set_array_member("config", props);
1047                         var cfgProperties = this.configToArray();
1048                         for(var i =0; i < cfgProperties.size;i++) {
1049                                 props.add_object_element(cfgProperties.get(i).toPropertyJSON(this));
1050                 }
1051                         // methods
1052  
1053                         var methods = new Json.Array();
1054                         ret.set_array_member("methods", methods);                    
1055                         foreach(var m in this.methods) {
1056                                 if (m.isEvent || m.isIgnored) {
1057                                         continue;
1058                                 }
1059                                 methods.add_object_element(m.toMethodJSON(this));
1060                         }
1061                         
1062                         // events
1063                         var events = new Json.Array();
1064                         ret.set_array_member("events", events);              
1065                     foreach(var m in this.methods) {
1066                         if (!m.isEvent || m.isIgnored) {
1067                                 continue;
1068                         }
1069                         events.add_object_element(m.toEventJSON(this));
1070                 }
1071                 return ret;
1072                 }
1073                 
1074                 // ?? can this be replaced with ???
1075                 public Json.Array paramsToJson()
1076                 {
1077                         var ret = new Json.Array();
1078                         foreach(var p in this.params) {
1079                                 //GLib.debug("got param: %s", p.asString());
1080                                 if (p.name.contains(".")) continue;// ?? why?                           
1081                                 var add = new Json.Object();
1082                                 add.set_string_member("name",p.name);                           
1083                                 add.set_string_member("type",p.type);
1084                                 add.set_string_member("desc",p.desc);
1085                                 add.set_boolean_member("isOptional",p.isOptional);
1086                                 ret.add_object_element(add) ;
1087                         }
1088                          
1089                         return ret;
1090                 
1091                 }
1092                 
1093                 // ?? can this be replaced with ???
1094         public Json.Array returnsToJson()
1095                 {
1096                         var ret = new Json.Array();
1097                         foreach(var p in this.returns) {
1098                                 //GLib.debug("got param: %s", p.asString());
1099                                 if (p.name.contains(".")) continue;// ?? why?                           
1100                                 var add = new Json.Object();
1101                                 add.set_string_member("name",p.name);                           
1102                                 add.set_string_member("type",p.type);
1103                                 add.set_string_member("desc",p.desc);
1104                  
1105                                 ret.add_object_element(add) ;
1106                         }
1107                          
1108                         return ret;
1109                 
1110                 }
1111                 
1112                  /**
1113                  * JSON files are lookup files for the documentation
1114                  * - can be used by IDE's or AJAX based doc tools
1115                  *  This is a simplified version..
1116                  * 
1117                  */
1118                 public Json.Object toClassJSON ()
1119                 {
1120                     // what we need to output to be usefull...
1121                     // a) props..
1122                     var cfgProperties = new Gee.ArrayList<DocTag>();
1123                     if (this.comment.getTag(DocTagTitle.SINGLETON).size < 1) {
1124                          cfgProperties = this.configToArray();
1125                          cfgProperties.sort((a,b) =>{
1126                                 return a.name.collate(b.name);
1127                         }); 
1128                     } 
1129                     var props = new Json.Array(); 
1130                     for(var i =0; i < cfgProperties.size;i++) {
1131                         props.add_object_element(  cfgProperties.get(i).toPropertyJSON(this) );
1132                     }
1133                     
1134                     ///// --- events
1135                     var ownEvents = new Gee.ArrayList<Symbol>();
1136                     for(var i =0; i < this.methods.size;i++) {
1137                                 var e = this.methods.get(i);
1138                                 if (e.isEvent && !e.isIgnored) {
1139                                         ownEvents.add(e);
1140                                 }
1141                         }; 
1142                         ownEvents.sort((a,b) => {
1143                                 return a.name.collate(b.name);
1144                         });
1145                     
1146                     var events = new Json.Array();
1147                      
1148                     for(var i =0; i < ownEvents.size;i++) {
1149                         events.add_object_element(ownEvents.get(i).toEventJSON(this));
1150                     } 
1151                      
1152                     // methods
1153                     var ownMethods = new Gee.ArrayList<Symbol>();
1154                     for(var i =0; i < this.methods.size;i++) {
1155                                 var e = this.methods.get(i);
1156                                 if (!e.isEvent && !e.isIgnored) {
1157                                         ownMethods.add(e);
1158                                 }
1159                         };
1160                         ownMethods.sort((a,b) => {
1161                                 return a.name.collate(b.name);
1162                         });
1163                     
1164                         var methods = new Json.Array();
1165                     for(var i =0; i < ownMethods.size;i++) {
1166                         methods.add_object_element(ownMethods.get(i).toMethodJSON(this));
1167                     }
1168                      
1169                     //println(props.toSource());
1170                     // we need to output:
1171                     //classname => {
1172                     //    propname => 
1173                     //        type=>
1174                     //        desc=>
1175                     //    }
1176                         var ret =  new Json.Object();
1177                         ret.set_array_member("props", props);
1178                         ret.set_array_member("events", events);
1179                         ret.set_array_member("methods", methods);
1180                         ret.set_boolean_member("isAbstract", this.isAbstract);
1181                         ret.set_boolean_member("isBuilderTop", this.isBuilderTop);
1182                         ret.set_array_member("implementations", this.stringArrayToJson(this.childClassesList));
1183                         //ret.set_object_member("childClasses", this.assocStringToJson(this.childClasses));
1184                         ret.set_array_member("tree_children", this.stringArrayToJson(this.tree_children));
1185                         ret.set_array_member("tree_parent", this.stringArrayToJson(this.tree_parent));
1186
1187                         
1188                 
1189                     return ret;
1190                     
1191                     
1192                     // b) methods
1193                     // c) events
1194                     
1195                     
1196                 }
1197                  
1198                 
1199                 public Json.Object toEventJSON (Symbol parent)
1200                 {
1201                         var add = new Json.Object();
1202                         add.set_string_member("name",this.name.substring(1,-1)); // remove'*' on events..
1203                         add.set_string_member("type","function");
1204                         add.set_string_member("desc",this.desc);
1205                         add.set_string_member("sig", this.makeFuncSkel());
1206                         add.set_string_member("memberOf", this.memberOf == parent.alias ? "" : this.memberOf);  
1207                         add.set_string_member("example", this.comment.getTagAsString(DocTagTitle.EXAMPLE));
1208                         add.set_string_member("deprecated", // as depricated is used as a flag...
1209                                         this.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
1210                                         "This has been deprecated: "+  this.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
1211                                         "");
1212                         add.set_string_member("since", this.comment.getTagAsString(DocTagTitle.SEE));
1213                         add.set_string_member("see", this.comment.getTagAsString(DocTagTitle.SEE));
1214                         // not supported or used yet?
1215                         //add.set_string_member("exceptions", m.comment.getTagAsString(DocTagTitle.THROWS));
1216                         //add.set_string_member("requires", m.comment.getTagAsString(DocTagTitle.REQUIRES));
1217                         
1218                         add.set_array_member("params", this.paramsToJson());
1219                         add.set_array_member("returns", this.returnsToJson());
1220                         
1221                         
1222                         
1223                         
1224                         
1225                                         
1226                         return add;
1227                 }
1228                 public Json.Object toMethodJSON (Symbol parent)
1229                 {
1230                         var add = new Json.Object();
1231                         add.set_string_member("name",this.name);
1232                         add.set_string_member("type","function");
1233                         add.set_string_member("desc",this.desc);
1234                         add.set_string_member("sig", this.makeMethodSkel());
1235                         add.set_boolean_member("static", this.isStatic);
1236                         add.set_string_member("memberOf", this.memberOf == parent.alias ? "" : this.memberOf);
1237                         
1238                         // we may as well add extended data here...
1239                         add.set_boolean_member("isStatic", this.isStatic);
1240                         add.set_boolean_member("isConstructor", this.isa == "CONSTRUCTOR");
1241                         add.set_boolean_member("isPrivate", this.isPrivate);
1242
1243                         add.set_string_member("example", this.comment.getTagAsString(DocTagTitle.EXAMPLE));
1244                         add.set_string_member("deprecated", // as depricated is used as a flag...
1245                                         this.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
1246                                         "This has been deprecated: "+ this.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
1247                                         "");
1248                         add.set_string_member("since", this.comment.getTagAsString(DocTagTitle.SINCE));
1249                         add.set_string_member("see", this.comment.getTagAsString(DocTagTitle.SEE));
1250                         // not supported or used yet?
1251                         add.set_string_member("exceptions", this.comment.getTagAsString(DocTagTitle.THROWS));
1252                         add.set_string_member("requires", this.comment.getTagAsString(DocTagTitle.REQUIRES));
1253                         add.set_array_member("params", this.paramsToJson());
1254                         add.set_array_member("returns", this.returnsToJson());
1255                          
1256                         
1257                         return add;
1258                 }
1259
1260          }
1261         //static string[] hide = { "$args" };
1262         //static string srcFile = "";    
1263 }
1264
1265
1266 /*
1267 Symbol.fromDump = function(t)
1268 {
1269     var ns = new Symbol();
1270     for (var i in t) {
1271         if (typeof(ns[i]) == "undefined") {
1272             println("ERR:no default for Symbol:"+ i);
1273         }
1274         ns[i] = t[i];
1275     }
1276     return ns;
1277 }
1278 */