Fix #6904 - JSON output for docs / editor
authorAlan Knowles <alan@roojs.com>
Fri, 30 Jul 2021 08:18:23 +0000 (16:18 +0800)
committerAlan Knowles <alan@roojs.com>
Fri, 30 Jul 2021 08:18:23 +0000 (16:18 +0800)
roojspacker/DocBuilder.vala
roojspacker/DocParser.vala
roojspacker/DocTag.vala
roojspacker/PackerRun.vala
roojspacker/Symbol.vala
roojspacker/SymbolSet.vala

index 76b71ce..c993fe5 100644 (file)
@@ -4,7 +4,7 @@
 namespace JSDOC 
 {
 
-       class DocBuilder : Object 
+       public class DocBuilder : Object 
        {
                
  
@@ -13,6 +13,14 @@ namespace JSDOC
                
                private SymbolSet symbolSet;
                
+               public Symbol getSymbol(string name) // wrapper for read only...
+               {
+                       return this.symbolSet.getSymbol(name);
+               }
+               
+               
+               
+               
                private Packer packer;
        
                public DocBuilder (Packer p) 
@@ -30,38 +38,36 @@ namespace JSDOC
        
                    this.parseSrcFiles();
                    
+                   DocParser.validateAugments();                   
+                   DocParser.fillChildClasses();
+                   DocParser.fillTreeChildren();
+                   
+                   
                    this.symbolSet = DocParser.symbols();
+                   
+                   
+                   var classes =  DocParser.classes();
                     
-                   // this currently uses the concept of publish.js...
                    
+                   // this currently uses the concept of publish.js...
+                  
                    if (PackerRun.singleton().opt_doc_dump_tree) {
                    
                    
-                       var symbols = this.symbolSet.values();
-                   
-                                
+                       
                                
                         
                                //print(JSON.stringify(symbols,null,4));
-                               var classes = new Gee.ArrayList<Symbol>();
-                               
-                               foreach(var symbol in symbols) {
-                                       if (symbol.isaClass()) { 
-                                               classes.add(symbol);
-                                       }
-                               }    
-                               classes.sort( (a,b) => {
-                                       return a.alias.collate(b.alias); 
-                               });
-                   
+                                
                        var jsonAll = new Json.Object(); 
+                       var ar = new Json.Array(); 
                                for (var i = 0, l = classes.size; i < l; i++) {
-                                   var symbol = classes.get(i);
-                                        
-                                   jsonAll.set_object_member(symbol.alias,  this.publishJSON(symbol));
+                                   var symbol = classes.get(i);    
+                                   //
+                                   ar.add_object_element(  symbol.toJson());
 
                                }
-                               
+                               jsonAll.set_array_member("data", ar);
                                var generator = new Json.Generator ();
                            var root = new Json.Node(Json.NodeType.OBJECT);
                   
@@ -175,92 +181,26 @@ namespace JSDOC
                    
                                 
                        DocParser.parse(ts, srcFile);
-                       /*
-                       if (useCache) {
-                               
-                               var ar = DocParser.symbolsToObject(srcFile);
-                               
-                               var builder = new Json.Builder ();
-                               builder.begin_array ();
-                               for (var i=0;i<ar.size;i++) {
-                               
-                                               builder.add_object_value (ar.get(i));
-                                       }
-                                       builder.end_array ();
-                                       Json.Generator generator = new Json.Generator ();
-                                       Json.Node root = builder.get_root ();
-                                       generator.set_root (root);
-                                       generator.pretty=  true;
-                                       generator.ident = 2;
-                                       generator.to_file(cacheFile);
-                       
-                        
-                           
-                                }
-                                */
+                      
                    }
                    
                     
                    
                    DocParser.finish();
-               }
-               /*
-
-            //var txs =
-            
-            var tr = new  TokenReader(this.packer);
-                       tr.keepDocs = true;
-                       tr.keepWhite = true;
-                       tr.keepComments = true;
-                       tr.sepIdents = false;
-                       tr.collapseWhite = false;
-                       tr.filename = src;
-            
+                   
+                   
+                   // this is probably not the best place for this..
+                  
+                   
 
-            var toks = tr.tokenize( new TextStream(src));
-            if (PackerRun.opt_dump_tokens) {
-                               toks.dump();
-                               return "";
-                               //GLib.Process.exit(0);
-                       }
-            
-            
-            var ts = new TokenStream(toks);
-        
-        
-        
-                     
-            DocParser.parse(ts, srcFile);
-            
-            if (useCache) {
-                       
-                       var ar = DocParser.symbolsToObject(srcFile);
-                       
-                       var builder = new Json.Builder ();
-               builder.begin_array ();
-               for (var i=0;i<ar.size;i++) {
-               
-                                       builder.add_object_value (ar.get(i));
-                               }
-                               builder.end_array ();
-                               Json.Generator generator = new Json.Generator ();
-                               Json.Node root = builder.get_root ();
-                               generator.set_root (root);
-                               generator.pretty=  true;
-                               generator.ident = 2;
-                               generator.to_file(cacheFile);
-            
-             
-                
-    //         }
-        }
-        
-        
-        
-        Parser.finish();
-    }
-    
-     */
+                   
+                   
+                   
+               }
+               
+                
+                
+                
        string tempdir;
         
                void publish() 
@@ -329,16 +269,7 @@ namespace JSDOC
                        this.makeSrcFile(file);
                    }
                    //print(JSON.stringify(symbols,null,4));
-                   var classes = new Gee.ArrayList<Symbol>();
-                   
-                   foreach(var symbol in symbols) {
-                               if (symbol.isaClass()) { 
-                                       classes.add(symbol);
-                               }
-                   }    
-                   classes.sort( (a,b) => {
-                               return a.alias.collate(b.alias); 
-                       });
+                   var classes = DocParser.classes();
                     
                     //GLib.debug("classTemplate Process : all classes");
                        
@@ -357,18 +288,18 @@ namespace JSDOC
                        
                        var   class_gen = new Json.Generator ();
                            var  class_root = new Json.Node(Json.NodeType.OBJECT);
-                               class_root.init_object(this.class_to_json(symbol));
+                               class_root.init_object(symbol.toClassDocJSON());
                                class_gen.set_root (class_root);
                                class_gen.pretty=  true;
                                class_gen.indent = 2;
-                               GLib.warning("writing JSON:  %s", PackerRun.singleton().opt_doc_target+"/symbols/" +symbol.alias+".json");
+                               GLib.debug("writing JSON:  %s", PackerRun.singleton().opt_doc_target+"/symbols/" +symbol.alias+".json");
                                this.writeJson(class_gen, PackerRun.singleton().opt_doc_target+"/symbols/" +symbol.alias+".json");
                        
-                       jsonAll.set_object_member(symbol.alias,  this.publishJSON(symbol));
+                       jsonAll.set_object_member(symbol.alias,  symbol.toClassJSON());
 
                    }
                    
-                   // outptu class truee
+                   // outptu class tree
                    
                    var   class_tree_gen = new Json.Generator ();
            var  class_tree_root = new Json.Node(Json.NodeType.ARRAY);
@@ -376,7 +307,7 @@ namespace JSDOC
                        class_tree_gen.set_root (class_tree_root);
                        class_tree_gen.pretty=  true;
                        class_tree_gen.indent = 2;
-                       GLib.warning("writing JSON:  %s", PackerRun.singleton().opt_doc_target+"/tree.json");
+                       GLib.debug("writing JSON:  %s", PackerRun.singleton().opt_doc_target+"/tree.json");
                        this.writeJson(class_tree_gen,PackerRun.singleton().opt_doc_target+"/tree.json");
                        size_t class_tree_l;
                        //GLib.debug("JSON: %s", class_tree_gen.to_data(out class_tree_l));
@@ -392,7 +323,7 @@ namespace JSDOC
                        generator.set_root (root);
                        generator.pretty=  true;
                        generator.indent = 2;
-                       GLib.warning("writing JSON:  %s", PackerRun.singleton().opt_doc_target+"/json/roodata.json");
+                       GLib.debug("writing JSON:  %s", PackerRun.singleton().opt_doc_target+"/json/roodata.json");
                        
                        
                        this.writeJson(generator,PackerRun.singleton().opt_doc_target+"/json/roodata.json");
@@ -408,136 +339,7 @@ namespace JSDOC
                    
                }
                
-               Json.Object class_to_json (Symbol cls)
-               {
-                       var ret = new Json.Object();
-                       ret.set_string_member("name", cls.alias);
-                       var ag = new Json.Array();
-                       ret.set_array_member("augments", ag);                   
-                       for(var ii = 0, il = cls.augments.size; ii < il; ii++) {
-                  var contributer = this.symbolSet.getSymbol(cls.augments[ii]);
-                  if (contributer == null) {
-                       continue;
-                       }
-                  ag.add_string_element(contributer.alias);
-            }
-            ret.set_string_member("name", cls.alias);  
-            ret.set_string_member("desc", cls.desc);
-               ret.set_boolean_member("isSingleton", cls.comment.getTag(DocTagTitle.SINGLETON).size > 0);
-               ret.set_boolean_member("isStatic", cls.isa != "CONSTRUCTOR");
-               ret.set_boolean_member("isBuiltin", cls.isBuiltin());
-               
-               // needded so that the class can fake a ctor..
-            ret.set_string_member("memberOf", cls.name);
-                       ret.set_string_member("example", cls.comment.getTagAsString(DocTagTitle.EXAMPLE));
-                   ret.set_string_member("deprecated", // as depricated is used as a flag...
-                                       cls.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
-                                       "This has been deprecated: "+  cls.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
-                               "");
-               ret.set_string_member("since", cls.comment.getTagAsString(DocTagTitle.SINCE));
-               ret.set_string_member("see", cls.comment.getTagAsString(DocTagTitle.SINCE));
-                       // not supported or used yet?
-                       //add.set_string_member("exceptions", m.comment.getTagAsString(DocTagTitle.EXCEPTIONS));
-                       //add.set_string_member("requires", m.comment.getTagAsString(DocTagTitle.REQUIRES));
-               ret.set_array_member("params", cls.paramsToJson());
-               ret.set_array_member("returns", new Json.Array()); 
-                               
-                       //ret.set_string_member("desc", cls.comment.getTagAsString(DocTagTitle.DESC));
-               /// fixme - @see ... any others..
-                       
-                       var props = new Json.Array(); 
-                       ret.set_array_member("config", props);
-                       var cfgProperties = cls.configToArray();
-                       for(var i =0; i < cfgProperties.size;i++) {
-                       var p = cfgProperties.get(i);
-                       var add = new Json.Object();
-                       add.set_string_member("name",p.name);
-                       add.set_string_member("type",p.type);
-                       add.set_string_member("desc",p.desc);
-                       add.set_string_member("memberOf",  p.memberOf);
-                       add.set_array_member("optvals",p.optvalues.size > 0 ? p.optvalue_as_json_array() : new Json.Array());
-                       props.add_object_element(add );
-                   }
-                    
-                   // methods
-
-                        
-                       var methods = new Json.Array();
-                       ret.set_array_member("methods", methods);                    
-                   foreach(var m in cls.methods) {
-                       if (m.isEvent || m.isIgnored) {
-                               continue;
-                       }
-                       
-                       var add = new Json.Object();
-                       add.set_string_member("name",m.name);
-                       //add.set_string_member("type","function");
-                       add.set_string_member("desc",m.desc);
-                       //add.set_string_member("sig", m.makeMethodSkel());
-                       add.set_boolean_member("isStatic", m.isStatic);
-                       add.set_boolean_member("isConstructor", m.isa == "CONSTRUCTOR");
-                       add.set_boolean_member("isPrivate", m.isPrivate);
-                       //add.set_string_member("instanceOf", m.comment.getTagAsString(DocTagTitle.INSTANCEOF));
-                       add.set_string_member("memberOf", m.memberOf);
-                       add.set_string_member("example", m.comment.getTagAsString(DocTagTitle.EXAMPLE));
-                       add.set_string_member("deprecated", // as depricated is used as a flag...
-                                       m.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
-                                       "This has been deprecated: "+  m.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
-                                       "");
-                       add.set_string_member("since", m.comment.getTagAsString(DocTagTitle.SINCE));
-                       add.set_string_member("see", m.comment.getTagAsString(DocTagTitle.SINCE));
-                       // not supported or used yet?
-                       //add.set_string_member("exceptions", m.comment.getTagAsString(DocTagTitle.EXCEPTIONS));
-                       //add.set_string_member("requires", m.comment.getTagAsString(DocTagTitle.REQUIRES));
-                       add.set_array_member("params", m.paramsToJson());
-                       add.set_array_member("returns", m.returnsToJson());
-                       
-                       /// fixme - @see ... any others..
-                         
-                       
-                       methods.add_object_element(add);
-                   }
-                   
-                   
-                       var events = new Json.Array();
-                       ret.set_array_member("events", events);              
-                   foreach(var m in cls.methods) {
-                       if (!m.isEvent || m.isIgnored) {
-                               continue;
-                       }
-                       
-                       var add = new Json.Object();
-                       add.set_string_member("name",m.name.substring(1)); // all prefixed with '*'...
-                       //add.set_string_member("type","function");
-                       add.set_string_member("desc",m.desc);
-                       //add.set_string_member("sig", m.makeMethodSkel());
-
-                       add.set_string_member("memberOf", m.memberOf);
-                       add.set_string_member("example", m.comment.getTagAsString(DocTagTitle.EXAMPLE));
-                       add.set_string_member("deprecated", // as depricated is used as a flag...
-                                       m.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
-                                       "This has been deprecated: "+  m.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
-                                       "");
-                       add.set_string_member("since", m.comment.getTagAsString(DocTagTitle.SINCE));
-                       add.set_string_member("see", m.comment.getTagAsString(DocTagTitle.SINCE));
-                       // not supported or used yet?
-                       //add.set_string_member("exceptions", m.comment.getTagAsString(DocTagTitle.EXCEPTIONS));
-                       //add.set_string_member("requires", m.comment.getTagAsString(DocTagTitle.REQUIRES));
-                       
-                       add.set_array_member("params", m.paramsToJson());
-                       add.set_array_member("returns", m.returnsToJson());
-                       
-                       /// fixme - @see ... any others..
-                         
-                       
-                       events.add_object_element(add);
-                   }
-                   
-                       
-                       
-               
-                       return ret;
-               }
                /**
                * needed as Json dumps .xXXX into same directory as it writes...
                */
@@ -559,115 +361,7 @@ namespace JSDOC
                        GLib.File.new_for_path(tmp).move( File.new_for_path(fname), GLib.FileCopyFlags.OVERWRITE);
                      
                }
-               
-               /**
-                * JSON files are lookup files for the documentation
-                * - can be used by IDE's or AJAX based doc tools
-                * 
-                * 
-                */
-               Json.Object publishJSON (Symbol data)
-               {
-                   // what we need to output to be usefull...
-                   // a) props..
-                   var cfgProperties = new Gee.ArrayList<DocTag>();
-                   if (data.comment.getTag(DocTagTitle.SINGLETON).size < 1) {
-                        cfgProperties = data.configToArray();
-                        cfgProperties.sort((a,b) =>{
-                               return a.name.collate(b.name);
-                       }); 
-                       
-                   } 
-                   
-                   var props = new Json.Array(); 
-                   //println(cfgProperties.toSource());
-                   
-                   for(var i =0; i < cfgProperties.size;i++) {
-                       var p = cfgProperties.get(i);
-                       var add = new Json.Object();
-                       add.set_string_member("name",p.name);
-                       add.set_string_member("type",p.type);
-                       add.set_string_member("desc",p.desc);
-                       add.set_string_member("memberOf", p.memberOf == data.alias ? "" : p.memberOf);
-                           
-                       if (p.optvalues.size > 0) {
-                            add.set_array_member("optvals",p.optvalue_as_json_array());
-                       }
-                       
-                       props.add_object_element(add );
-                   }
-                   
-                   ///// --- events
-                   var ownEvents = new Gee.ArrayList<Symbol>();
-                   for(var i =0; i < data.methods.size;i++) {
-                               var e = data.methods.get(i);
-                               if (e.isEvent && !e.isIgnored) {
-                                       ownEvents.add(e);
-                               }
-                       }; 
-                       ownEvents.sort((a,b) => {
-                               return a.name.collate(b.name);
-                       });
-                   
-                   var events = new Json.Array();
-                    
-                   for(var i =0; i < ownEvents.size;i++) {
-                       var m = ownEvents.get(i);
-                       var add = new Json.Object();
-                       add.set_string_member("name",m.name.substring(1,-1)); // remove'*' on events..
-                       add.set_string_member("type","function");
-                       add.set_string_member("desc",m.desc);
-                       add.set_string_member("sig", m.makeFuncSkel());
-                       add.set_string_member("memberOf", m.memberOf == data.alias ? "" : m.memberOf);                  
-                       events.add_object_element(add);
-                   } 
-                    
-                   // methods
-                   var ownMethods = new Gee.ArrayList<Symbol>();
-                   for(var i =0; i < data.methods.size;i++) {
-                               var e = data.methods.get(i);
-                               if (!e.isEvent && !e.isIgnored) {
-                                       ownMethods.add(e);
-                               }
-                       };
-                       ownMethods.sort((a,b) => {
-                               return a.name.collate(b.name);
-                       });
-                   
-                       var methods = new Json.Array();
-                    
-                   for(var i =0; i < ownMethods.size;i++) {
-                       var m = ownMethods.get(i);
-                       var add = new Json.Object();
-                       add.set_string_member("name",m.name);
-                       add.set_string_member("type","function");
-                       add.set_string_member("desc",m.desc);
-                       add.set_string_member("sig", m.makeMethodSkel());
-                       add.set_boolean_member("static", m.isStatic);
-                       add.set_string_member("memberOf", m.memberOf == data.alias ? "" : m.memberOf);  
-                       methods.add_object_element(add);
-                   }
-                    
-                   //println(props.toSource());
-                   // we need to output:
-                   //classname => {
-                   //    propname => 
-                   //        type=>
-                   //        desc=>
-                   //    }
-                       var ret =  new Json.Object();
-                       ret.set_array_member("props", props);
-                       ret.set_array_member("events", events);
-                       ret.set_array_member("methods", methods);
-               
-                   return ret;
-                   
-                   
-                   // b) methods
-                   // c) events
-                   
-                   
-               }
+                
                Gee.HashMap<string,Json.Object> class_tree_map;
                Json.Array class_tree_top;
                
@@ -688,6 +382,7 @@ namespace JSDOC
                add.set_string_member("name", name);
                add.set_array_member("cn", new Json.Array());
                add.set_boolean_member("is_class", is_class);
+               
                this.class_tree_map.set(name, add);
                var bits = name.split(".");
                if (bits.length == 1) {
index ccfcc86..ddbdf21 100644 (file)
@@ -1,6 +1,11 @@
 
 namespace JSDOC
 {
+       public errordomain DocParserError {
+            InvalidAugments,
+            InvalidDocChildren
+    }
  
        public class DocParser : Object 
        {
@@ -37,9 +42,133 @@ namespace JSDOC
            public static string currentSourceFile;
     
 
+               public static Gee.ArrayList<Symbol> classes()
+               {
+                       var classes = new Gee.ArrayList<Symbol>();
+                       foreach(var symbol in DocParser.symbols().values()) {
+                               if (symbol.isaClass()) { 
+                                       classes.add(symbol);
+                               }
+                       }    
+                       classes.sort( (a,b) => {
+                               return a.alias.collate(b.alias); 
+                       });
+                       return classes;
+               }
+
+               public static void  validateAugments()
+               {
+                       var classes =  DocParser.classes();
+                   foreach (var cls in classes) {
+                            var ar = cls.augments.slice(0, cls.augments.size); // copy?
+                           cls.augments.clear();
+                               for(var ii = 0  ; ii <  ar.size; ii++) {
+                                       var contributer = DocParser.symbols().getSymbol(ar[ii]);
+                                       if (contributer == null) {
+                                               GLib.warning("Looking at Class %s, could not find augments %s", 
+                                                               cls.alias, ar[ii]);
+                                               continue;
+                                       }
+                                       cls.augments.add(ar[ii]); 
+                               }
+                       }
+               }
+
+               public static void  fillChildClasses()
+               {
+                        var classes =  DocParser.classes();
+                        foreach (var cls in classes) {
+                       foreach (var lookcls in classes) {
+                                       if (lookcls.augments.contains(cls.alias)) {
+                                               var extends = "";
+                                               if (lookcls.augments.size > 0) {
+                                                       extends = lookcls.augments.get(0);
+                                                       if ( extends  == lookcls.alias) {
+                                                               extends = lookcls.augments.size > 1 ? lookcls.augments.get(1) : "";
+                                                       }
+                                               }
+                                               cls.addChildClass(lookcls.alias, extends);
+                                       }
+                               }
+               }
+               }
                
-                
+               public static bool   isValidChild(Symbol cls, string cn)
+               {
+                       var sy = DocParser.symbols().getSymbol(cn);
+               if (sy == null) {
+                       GLib.warning("fillTreeChildren: Looking at Class %s, could not find child %s", 
+                                               cls.alias, cn);
+                               return false;
+                       }
+                       if (sy.isAbstract) {
+                               GLib.debug("fillTreeChildren: checking %s child is an abstract %s", cls.alias, cn);
+                               return false;
+                       }
+                       if (sy.tree_parent.size > 0) {
+                               var skip  = true;
+                               foreach (var pp in sy.tree_parent) {
+                                       if (pp == "none") {
+                                               GLib.debug("fillTreeChildren : checking %s - skip due to tree_parent match: %s", 
+                                                       cls.alias, pp);
+                                               return false;
+                                       }
+                                       if (pp == cls.alias) {
+                                               skip = false;
+                                               break;
+                                       }
+                               }
+                               if (skip) {
+                                       GLib.debug("fillTreeChildren : checking %s - skip due to no tree_parent match", 
+                                                       cls.alias);
+                                       return false;
+                               }
+                       }
+                       return true;
+                       
+                       
+               }
                
+                
+               public static void  fillTreeChildren()
+               {
+                        // lookup symbol : builder.getSymbol()
+                        
+                        var classes =  DocParser.classes();
+                        foreach (var cls in classes) {
+                               if (cls.tree_children.size < 1) {
+                                       GLib.debug("fillTreeChildren : skip - no children %s", cls.alias);
+                                       continue;
+                               }
+                               GLib.debug("fillTreeChildren : checking %s", cls.alias);
+                               
+                               var ar = new Gee.ArrayList<string>();
+                               foreach(var cn in cls.tree_children) {
+                                       ar.add(cn);
+                               }
+                               cls.tree_children.clear();
+                       foreach(var cn in ar) {
+                               GLib.debug("fillTreeChildren : checking %s - child %s", cls.alias, cn);
+                               var sy = DocParser.symbols().getSymbol(cn);
+                         
+                         
+                                       
+                                       if (DocParser.isValidChild(cls, cn)) {
+                                               GLib.debug("fillTreeChildren : checking %s - add %s",  cls.alias ,cn);
+                                               cls.tree_children.add(cn);
+                                       }
+                                       foreach(var cc in sy.childClassesList) {
+
+                                               if (DocParser.isValidChild(cls, cc)) {
+                                                       cls.tree_children.add(cc);
+                                                       GLib.debug("fillTreeChildren : checking %s - add %s",  cls.alias ,cc);
+                                               }
+                                       }
+                               }
+                       }       
+                        
+                   
+               }
                
                public static void parse(TokenStream ts, string srcFile) 
                {
index 4074807..df050d7 100644 (file)
@@ -43,7 +43,14 @@ namespace JSDOC
                MEMBEROF,
                PUBLIC,
                SCOPE,
-               SCOPEALIAS
+               SCOPEALIAS,
+               
+               // these are some we have added for creating trees etc..
+               CHILDREN, // what classes can be added as child in a tree
+               PARENT,  // restrict what the class can be added to.
+               ABSTRACT, // is the class abstract
+               BUILDER_TOP // can the element be used as a top level in the gui builder
+  
   
        }
        
@@ -183,13 +190,15 @@ namespace JSDOC
                                return src;
                    }
                    
-                   //GLib.debug("nibbleTitle: regexmatches %d : %s",
-                   //           mi.get_match_count(), 
-                   //           mi.fetch(1).up());
+                   // convert the @xxx to a DocTagTitle
+                   // wonder if caching this as a GeeHashmap would be quicker?
                    
                    EnumClass enumc = (EnumClass) typeof (DocTagTitle).class_ref ();
 
-                   unowned EnumValue? eval = enumc.get_value_by_name ( "JSDOC_DOC_TAG_TITLE_"+  mi.fetch(1).up());
+                   unowned EnumValue? eval = enumc.get_value_by_name(
+                       //       "JSDOC_DOC_TAG_TITLE_"+  mi.fetch(1).up()
+                                "JSDOC_DOC_TAG_TITLE_"+  mi.fetch(1).up().replace("-", "_")
+                );
                    if (eval == null) {
                                throw new DocTagException.INVALID_TITLE("title not supported ??");
                                return src;
@@ -316,6 +325,17 @@ namespace JSDOC
                        
                        
                }
+               public Json.Object toPropertyJSON (Symbol parent)
+               {
+                       
+                       var add = new Json.Object();
+                       add.set_string_member("name",this.name);
+                       add.set_string_member("type",this.type);
+                       add.set_string_member("desc",this.desc);
+                       add.set_string_member("memberOf", this.memberOf == parent.alias ? "" : this.memberOf);
+                   return add;
+           }   
+               
                
        }
 }
index 9445994..db5494c 100644 (file)
@@ -353,7 +353,7 @@ namespace JSDOC
                        }  
                        
                        var run_pack = false;
-                       if (opt_target != null || opt_debug_target != null || opt_dump_tokens) {
+                       if (opt_target != null || opt_debug_target != null || opt_dump_tokens ) {
                                // do the actual packing...
                                p.pack( opt_target == null ? "" : opt_target ,
                                                opt_debug_target == null ? "" :  opt_debug_target );
@@ -363,10 +363,12 @@ namespace JSDOC
                                }
                                return;
                }
-               if (opt_doc_target != null) {
+               if (opt_doc_target != null || opt_doc_dump_tree) {
                                // remove trailing /
-                       opt_doc_target = opt_doc_target.has_suffix("/") ? 
-                                       opt_doc_target.substring(0, opt_doc_target.length-1) : opt_doc_target;
+                               if (opt_doc_target  != null ) {
+                                   opt_doc_target = opt_doc_target.has_suffix("/") ? 
+                                               opt_doc_target.substring(0, opt_doc_target.length-1) : opt_doc_target;
+                       }
                        var d = new JSDOC.DocBuilder(p);
                        return;
                } 
index 2422900..61c9da2 100644 (file)
@@ -96,11 +96,16 @@ namespace JSDOC {
                public Gee.ArrayList<DocTag> returns;
                private Gee.ArrayList<string> see ;
 
-               public Gee.ArrayList<string> childClasses;
+               public Gee.HashMap<string,Gee.ArrayList<string>> childClasses;
+               public Gee.ArrayList<string> childClassesList;
                public Gee.ArrayList<string> inheritsFrom;
-        public Gee.HashMap<string,DocTag>cfgs;
-        
-        
+               public Gee.HashMap<string,DocTag>cfgs;
+
+
+               public Gee.ArrayList<string> tree_parent;
+               public Gee.ArrayList<string> tree_children;
+               
+
         public DocComment comment;
                 
         //$args : [], // original arguments used when constructing.
@@ -116,15 +121,17 @@ namespace JSDOC {
         string example = "";
         
 
-        public string isa = "OBJECT"; // OBJECT//FUNCTION
+               public string isa = "OBJECT"; // OBJECT//FUNCTION
         
-        public bool isEvent = false;
-        public bool isConstant = false;
-        public bool isIgnored = false;
-        public bool isInner = false;
-        public bool isNamespace = false;
-        public bool isPrivate = false;
-        public bool isStatic = false;
+               public bool isEvent = false;
+               public bool isConstant = false;
+               public bool isIgnored = false;
+               public bool isInner = false;
+               public bool isNamespace = false;
+               public bool isPrivate = false;
+               public bool isStatic = false;
+               public bool isAbstract = false;
+               public bool isBuilderTop = false;
         
         public string memberOf = "";
 
@@ -176,10 +183,15 @@ namespace JSDOC {
  
             
             this.cfgs = new Gee.HashMap<string,DocTag>();
-            // derived later?
+            // what is this?
             this.inheritsFrom = new Gee.ArrayList<string>();
 
-            this.childClasses = new Gee.ArrayList<string>();
+            this.childClasses = new Gee.HashMap<string,Gee.ArrayList<string>>();
+            this.childClassesList = new Gee.ArrayList<string>();
+            
+            this.tree_parent = new Gee.ArrayList<string>();
+            this.tree_children = new Gee.ArrayList<string>();
+            
              
             this.comment = new DocComment();
             this.comment.isUserComment =  false;
@@ -237,7 +249,8 @@ namespace JSDOC {
             
         }
 
-        void tagsFromComment() {
+        void tagsFromComment() 
+        {
             // @author
             var authors = this.comment.getTag(DocTagTitle.AUTHOR);
             if (authors.size > 0) {
@@ -676,18 +689,38 @@ namespace JSDOC {
                 this.alias = this.name;
             }
 
-            /*~t
-                // todo
-            */
+           
              
             // @public
             if (this.comment.getTag(DocTagTitle.PUBLIC).size > 0) {
                 this.isPrivate = false;
             }
+             
+            // @children
+             if (this.comment.getTag(DocTagTitle.CHILDREN).size > 0) {
+                foreach(var s in this.comment.getTag(DocTagTitle.CHILDREN).get(0).desc.strip().split(" ")) {
+                       this.tree_children.add(s);
+               }
+            }
+            // @parent
+             if (this.comment.getTag(DocTagTitle.PARENT).size > 0) {
+                foreach(var s in this.comment.getTag(DocTagTitle.PARENT).get(0).desc.strip().split(" ")) {
+                       this.tree_parent.add(s);
+               }
+            }
+                        
+            // @abstract
+            if (this.comment.getTag(DocTagTitle.ABSTRACT).size > 0) {
+                this.isAbstract = true;
+            }
+                       // @builder-top            
+                       if (this.comment.getTag(DocTagTitle.BUILDER_TOP).size > 0) {
+                this.isBuilderTop = true;
+            }
             
-            /*~t
-                // todo
-            */
+            
+            
+             
         }
 
         public bool is (string what) {
@@ -781,6 +814,16 @@ namespace JSDOC {
             thisProperties.add(symbol); // new property with this alias
         }
         
+        public void addChildClass(string clsname, string parent) 
+        {
+               if (!this.childClasses.has_key( parent)) {
+                       this.childClasses.set(parent, new Gee.ArrayList<string>());
+               }
+               this.childClasses.get(parent).add(clsname);
+               this.childClassesList.add(clsname);
+       }
+         
+        
         public void addDocTag(DocTag docTag)
         {
             this.comment.tags.add(docTag);
@@ -849,41 +892,7 @@ namespace JSDOC {
                        }
                        return ret + ")";
                }
-               
-               public Json.Array paramsToJson()
-               {
-                       var ret = new Json.Array();
-                       foreach(var p in this.params) {
-                               //GLib.debug("got param: %s", p.asString());
-                               if (p.name.contains(".")) continue;// ?? why?                           
-                               var add = new Json.Object();
-                               add.set_string_member("name",p.name);                           
-                               add.set_string_member("type",p.type);
-                               add.set_string_member("desc",p.desc);
-                               add.set_boolean_member("isOptional",p.isOptional);
-                               ret.add_object_element(add) ;
-                       }
-                        
-                       return ret;
-               
-               }
-       public Json.Array returnsToJson()
-               {
-                       var ret = new Json.Array();
-                       foreach(var p in this.returns) {
-                               //GLib.debug("got param: %s", p.asString());
-                               if (p.name.contains(".")) continue;// ?? why?                           
-                               var add = new Json.Object();
-                               add.set_string_member("name",p.name);                           
-                               add.set_string_member("type",p.type);
-                               add.set_string_member("desc",p.desc);
-                
-                               ret.add_object_element(add) ;
-                       }
-                        
-                       return ret;
-               
-               }
+       
                public Json.Array stringArrayToJson( Gee.ArrayList<string> ar) 
                {
                        var ret = new Json.Array();
@@ -912,7 +921,15 @@ namespace JSDOC {
                
                } 
                
+               public Json.Object assocStringToJson( Gee.HashMap<string,Gee.ArrayList<string>> ar) 
+               {
+                       var ret = new Json.Object();
+                       foreach(var a in ar.keys) {
+                               ret.set_array_member(a, this.stringArrayToJson(ar.get(a)));
+                       }
+                       return ret;
                
+               } 
                
                public Json.Object assocDocTagToJson( Gee.HashMap<string,DocTag> ar) 
                {
@@ -924,11 +941,28 @@ namespace JSDOC {
                
                } 
                
-               
+               /**
+               * direct Json Dump
+               */
                public Json.Object toJson()
                {
                        var ret = new Json.Object();
                        ret.set_string_member("name", this.name);
+                       ret.set_object_member("comment", this.comment.toJson()); //contains doctags?
+                       ret.set_boolean_member("isEvent", this.isEvent);
+                       ret.set_boolean_member("isConstant", this.isConstant);
+                       ret.set_boolean_member("isIgnored", this.isIgnored);
+                       ret.set_boolean_member("isInner", this.isInner);
+                       ret.set_boolean_member("isNamespace", this.isNamespace);
+                       ret.set_boolean_member("isPrivate", this.isPrivate);
+                       ret.set_boolean_member("isStatic", this.isStatic);
+                       ret.set_boolean_member("isAbstract", this.isAbstract);
+                       ret.set_boolean_member("isBuilderTop", this.isBuilderTop);      
+                       ret.set_string_member("memberOf", this.memberOf);
+                       ret.set_array_member("tree_children", this.stringArrayToJson(this.tree_children));
+                       ret.set_array_member("tree_parent", this.stringArrayToJson(this.tree_parent));
+                       
+                       
                        ret.set_array_member("params", this.docTagsArrayToJson(this.params));
 
                        ret.set_array_member("augments", this.stringArrayToJson(this.augments));
@@ -938,10 +972,10 @@ namespace JSDOC {
                        ret.set_array_member("requires", this.stringArrayToJson(this.requires));
                        ret.set_array_member("returns", this.docTagsArrayToJson(this.returns));
                        ret.set_array_member("see", this.stringArrayToJson(this.see));
-                       ret.set_array_member("childClasses", this.stringArrayToJson(this.childClasses));
+                       ret.set_object_member("childClasses", this.assocStringToJson(this.childClasses));
                        ret.set_array_member("inheritsFrom", this.stringArrayToJson(this.inheritsFrom));
                        ret.set_object_member("cfgs", this.assocDocTagToJson(this.cfgs));
-                       ret.set_object_member("comment", this.comment.toJson());
+
                      //$args : [], // original arguments used when constructing.
  
                        ret.set_string_member("alias", this.alias);
@@ -955,34 +989,274 @@ namespace JSDOC {
                        
                        ret.set_string_member("isa", this.isa);
 
-                       ret.set_boolean_member("isEvent", this.isEvent);
-                       ret.set_boolean_member("isConstant", this.isConstant);
-                       ret.set_boolean_member("isIgnored", this.isIgnored);
-                       ret.set_boolean_member("isInner", this.isInner);
-                       ret.set_boolean_member("isNamespace", this.isNamespace);
-                       ret.set_boolean_member("isPrivate", this.isPrivate);
-                       ret.set_boolean_member("isStatic", this.isStatic);
-                       ret.set_string_member("memberOf", this.memberOf);
+
+
                        return ret;
                }
+               /**
+               * This is the more detail Class output for documentation body text
+               */
                
                
+               public Json.Object toClassDocJSON ()
+               {
+                       var ret = new Json.Object();
+                       ret.set_string_member("name", this.alias);
+                       
+                       
+                       var ag = new Json.Array();
+                       ret.set_array_member("augments", this.stringArrayToJson(this.augments));
+                       ret.set_object_member("childClasses", this.assocStringToJson(this.childClasses));
+                       
+                       ret.set_array_member("tree_children", this.stringArrayToJson(this.tree_children));
+                       ret.set_array_member("tree_parent", this.stringArrayToJson(this.tree_parent));
+
+                       
+                       ret.set_string_member("name", this.alias);  
+                       ret.set_string_member("desc", this.desc);
+                       ret.set_boolean_member("isSingleton", this.comment.getTag(DocTagTitle.SINGLETON).size > 0);
+                       ret.set_boolean_member("isStatic", this.isa != "CONSTRUCTOR");
+                       ret.set_boolean_member("isBuiltin", this.isBuiltin());
+                       ret.set_boolean_member("isAbstract", this.isAbstract);
+                       ret.set_boolean_member("isBuilderTop", this.isBuilderTop);                      
+
+                       // needded so that the class can fake a ctor..
+                       ret.set_string_member("memberOf", this.name);
+                       ret.set_string_member("example", this.comment.getTagAsString(DocTagTitle.EXAMPLE));
+                       ret.set_string_member("deprecated", // as depricated is used as a flag...
+                               this.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
+                               "This has been deprecated: "+  this.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
+                       "");
+                       ret.set_string_member("since", this.comment.getTagAsString(DocTagTitle.SINCE));
+                       ret.set_string_member("see", this.comment.getTagAsString(DocTagTitle.SEE));
+                       // ?? ctor? is that listed with the outer class?
+                       
+                       
+                       
+                       // this must be for the CTOR?
+                       ret.set_array_member("params", this.paramsToJson());
+                       ret.set_array_member("returns", new Json.Array()); // this is a placeholder - classes dont have returns..
+               ret.set_string_member("throws", this.comment.getTagAsString(DocTagTitle.THROWS));
+                       ret.set_string_member("requires", this.comment.getTagAsString(DocTagTitle.REQUIRES));
+                       
+                       
+                       var props = new Json.Array(); 
+                       ret.set_array_member("config", props);
+                       var cfgProperties = this.configToArray();
+                       for(var i =0; i < cfgProperties.size;i++) {
+                               props.add_object_element(cfgProperties.get(i).toPropertyJSON(this));
+               }
+                       // methods
+                       var methods = new Json.Array();
+                       ret.set_array_member("methods", methods);                    
+                       foreach(var m in this.methods) {
+                               if (m.isEvent || m.isIgnored) {
+                                       continue;
+                               }
+                               methods.add_object_element(m.toMethodJSON(this));
+                       }
+                       
+                       // events
+                       var events = new Json.Array();
+                       ret.set_array_member("events", events);              
+                   foreach(var m in this.methods) {
+                       if (!m.isEvent || m.isIgnored) {
+                               continue;
+                       }
+                       events.add_object_element(m.toEventJSON(this));
+               }
+               return ret;
+               }
                
+               // ?? can this be replaced with ???
+               public Json.Array paramsToJson()
+               {
+                       var ret = new Json.Array();
+                       foreach(var p in this.params) {
+                               //GLib.debug("got param: %s", p.asString());
+                               if (p.name.contains(".")) continue;// ?? why?                           
+                               var add = new Json.Object();
+                               add.set_string_member("name",p.name);                           
+                               add.set_string_member("type",p.type);
+                               add.set_string_member("desc",p.desc);
+                               add.set_boolean_member("isOptional",p.isOptional);
+                               ret.add_object_element(add) ;
+                       }
+                        
+                       return ret;
                
+               }
                
+               // ?? can this be replaced with ???
+       public Json.Array returnsToJson()
+               {
+                       var ret = new Json.Array();
+                       foreach(var p in this.returns) {
+                               //GLib.debug("got param: %s", p.asString());
+                               if (p.name.contains(".")) continue;// ?? why?                           
+                               var add = new Json.Object();
+                               add.set_string_member("name",p.name);                           
+                               add.set_string_member("type",p.type);
+                               add.set_string_member("desc",p.desc);
+                
+                               ret.add_object_element(add) ;
+                       }
+                        
+                       return ret;
                
+               }
                
+                /**
+                * JSON files are lookup files for the documentation
+                * - can be used by IDE's or AJAX based doc tools
+                *  This is a simplified version..
+                * 
+                */
+               public Json.Object toClassJSON ()
+               {
+                   // what we need to output to be usefull...
+                   // a) props..
+                   var cfgProperties = new Gee.ArrayList<DocTag>();
+                   if (this.comment.getTag(DocTagTitle.SINGLETON).size < 1) {
+                        cfgProperties = this.configToArray();
+                        cfgProperties.sort((a,b) =>{
+                               return a.name.collate(b.name);
+                       }); 
+                   } 
+                   var props = new Json.Array(); 
+                   for(var i =0; i < cfgProperties.size;i++) {
+                       props.add_object_element(  cfgProperties.get(i).toPropertyJSON(this) );
+                   }
+                   
+                   ///// --- events
+                   var ownEvents = new Gee.ArrayList<Symbol>();
+                   for(var i =0; i < this.methods.size;i++) {
+                               var e = this.methods.get(i);
+                               if (e.isEvent && !e.isIgnored) {
+                                       ownEvents.add(e);
+                               }
+                       }; 
+                       ownEvents.sort((a,b) => {
+                               return a.name.collate(b.name);
+                       });
+                   
+                   var events = new Json.Array();
+                    
+                   for(var i =0; i < ownEvents.size;i++) {
+                       events.add_object_element(ownEvents.get(i).toEventJSON(this));
+                   } 
+                    
+                   // methods
+                   var ownMethods = new Gee.ArrayList<Symbol>();
+                   for(var i =0; i < this.methods.size;i++) {
+                               var e = this.methods.get(i);
+                               if (!e.isEvent && !e.isIgnored) {
+                                       ownMethods.add(e);
+                               }
+                       };
+                       ownMethods.sort((a,b) => {
+                               return a.name.collate(b.name);
+                       });
+                   
+                       var methods = new Json.Array();
+                   for(var i =0; i < ownMethods.size;i++) {
+                       methods.add_object_element(ownMethods.get(i).toMethodJSON(this));
+                   }
+                    
+                   //println(props.toSource());
+                   // we need to output:
+                   //classname => {
+                   //    propname => 
+                   //        type=>
+                   //        desc=>
+                   //    }
+                       var ret =  new Json.Object();
+                       ret.set_array_member("props", props);
+                       ret.set_array_member("events", events);
+                       ret.set_array_member("methods", methods);
+                       ret.set_boolean_member("isAbstract", this.isAbstract);
+                       ret.set_boolean_member("isBuilderTop", this.isBuilderTop);
+                       ret.set_object_member("childClasses", this.assocStringToJson(this.childClasses));                       
+                       ret.set_array_member("tree_children", this.stringArrayToJson(this.tree_children));
+                       ret.set_array_member("tree_parent", this.stringArrayToJson(this.tree_parent));
+
+                       
                
-               
-               
-       }
-       
-       
+                   return ret;
+                   
+                   
+                   // b) methods
+                   // c) events
+                   
+                   
+               }
+                
+               
+               public Json.Object toEventJSON (Symbol parent)
+               {
+                       var add = new Json.Object();
+                       add.set_string_member("name",this.name.substring(1,-1)); // remove'*' on events..
+                       add.set_string_member("type","function");
+                       add.set_string_member("desc",this.desc);
+                       add.set_string_member("sig", this.makeFuncSkel());
+                       add.set_string_member("memberOf", this.memberOf == parent.alias ? "" : this.memberOf);  
+                       add.set_string_member("example", this.comment.getTagAsString(DocTagTitle.EXAMPLE));
+                       add.set_string_member("deprecated", // as depricated is used as a flag...
+                                       this.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
+                                       "This has been deprecated: "+  this.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
+                                       "");
+                       add.set_string_member("since", this.comment.getTagAsString(DocTagTitle.SEE));
+                       add.set_string_member("see", this.comment.getTagAsString(DocTagTitle.SEE));
+                       // not supported or used yet?
+                       //add.set_string_member("exceptions", m.comment.getTagAsString(DocTagTitle.THROWS));
+                       //add.set_string_member("requires", m.comment.getTagAsString(DocTagTitle.REQUIRES));
+                       
+                       add.set_array_member("params", this.paramsToJson());
+                       add.set_array_member("returns", this.returnsToJson());
+                       
+                       
+                       
+                       
+                       
+                                       
+                       return add;
+               }
+               public Json.Object toMethodJSON (Symbol parent)
+               {
+                       var add = new Json.Object();
+                       add.set_string_member("name",this.name);
+                       add.set_string_member("type","function");
+                       add.set_string_member("desc",this.desc);
+                       add.set_string_member("sig", this.makeMethodSkel());
+                       add.set_boolean_member("static", this.isStatic);
+                       add.set_string_member("memberOf", this.memberOf == parent.alias ? "" : this.memberOf);
+                       
+                       // we may as well add extended data here...
+                       add.set_boolean_member("isStatic", this.isStatic);
+                       add.set_boolean_member("isConstructor", this.isa == "CONSTRUCTOR");
+                       add.set_boolean_member("isPrivate", this.isPrivate);
+
+                       add.set_string_member("example", this.comment.getTagAsString(DocTagTitle.EXAMPLE));
+                       add.set_string_member("deprecated", // as depricated is used as a flag...
+                                       this.comment.getTag(DocTagTitle.DEPRECATED).size > 0 ? 
+                                       "This has been deprecated: "+ this.comment.getTagAsString(DocTagTitle.DEPRECATED) : 
+                                       "");
+                       add.set_string_member("since", this.comment.getTagAsString(DocTagTitle.SINCE));
+                       add.set_string_member("see", this.comment.getTagAsString(DocTagTitle.SEE));
+                       // not supported or used yet?
+                       add.set_string_member("exceptions", this.comment.getTagAsString(DocTagTitle.THROWS));
+                       add.set_string_member("requires", this.comment.getTagAsString(DocTagTitle.REQUIRES));
+                       add.set_array_member("params", this.paramsToJson());
+                       add.set_array_member("returns", this.returnsToJson());
+                        
+                       
+                       return add;
+               }
+
+        }
        //static string[] hide = { "$args" };
-       //static string srcFile = "";
-        
+       //static string srcFile = "";    
 }
 
 
index bf82b2a..c9ec2ae 100644 (file)
@@ -25,7 +25,7 @@ namespace JSDOC {
                                return this.__index;
                        }
                }
-                
+               // CTOR - do nothing..?
                public SymbolSet ()
                {
 
@@ -295,7 +295,7 @@ namespace JSDOC {
                     
                      
                     if (contributer != null) {
-                        contributer.childClasses.add(symbol.alias);
+                        //contributer.childClasses.add(symbol.alias); << removed we do this in one go later.
                         symbol.inheritsFrom.add(contributer.alias);
                         //if (!isUnique(symbol.inheritsFrom)) {
                         //    imports.BuildDocs.Options.LOG.warn("Can't resolve augments: Circular reference: "+symbol.alias+" inherits from "+contributer.alias+" more than once.");