From: Alan Knowles Date: Fri, 30 Jul 2021 08:18:23 +0000 (+0800) Subject: Fix #6904 - JSON output for docs / editor X-Git-Tag: release-1.5~14 X-Git-Url: http://git.roojs.org/?p=roojspacker;a=commitdiff_plain;h=88afc980b9cccd701a0384c62ccf25cfbec29447 Fix #6904 - JSON output for docs / editor --- diff --git a/roojspacker/DocBuilder.vala b/roojspacker/DocBuilder.vala index 76b71ce..c993fe5 100644 --- a/roojspacker/DocBuilder.vala +++ b/roojspacker/DocBuilder.vala @@ -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(); - - 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(); - - 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(); - 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(); - 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(); - 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 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) { diff --git a/roojspacker/DocParser.vala b/roojspacker/DocParser.vala index ccfcc86..ddbdf21 100644 --- a/roojspacker/DocParser.vala +++ b/roojspacker/DocParser.vala @@ -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 classes() + { + var classes = new Gee.ArrayList(); + 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(); + 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) { diff --git a/roojspacker/DocTag.vala b/roojspacker/DocTag.vala index 4074807..df050d7 100644 --- a/roojspacker/DocTag.vala +++ b/roojspacker/DocTag.vala @@ -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; + } + } } diff --git a/roojspacker/PackerRun.vala b/roojspacker/PackerRun.vala index 9445994..db5494c 100644 --- a/roojspacker/PackerRun.vala +++ b/roojspacker/PackerRun.vala @@ -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; } diff --git a/roojspacker/Symbol.vala b/roojspacker/Symbol.vala index 2422900..61c9da2 100644 --- a/roojspacker/Symbol.vala +++ b/roojspacker/Symbol.vala @@ -96,11 +96,16 @@ namespace JSDOC { public Gee.ArrayList returns; private Gee.ArrayList see ; - public Gee.ArrayList childClasses; + public Gee.HashMap> childClasses; + public Gee.ArrayList childClassesList; public Gee.ArrayList inheritsFrom; - public Gee.HashMapcfgs; - - + public Gee.HashMapcfgs; + + + public Gee.ArrayList tree_parent; + public Gee.ArrayList 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(); - // derived later? + // what is this? this.inheritsFrom = new Gee.ArrayList(); - this.childClasses = new Gee.ArrayList(); + this.childClasses = new Gee.HashMap>(); + this.childClassesList = new Gee.ArrayList(); + + this.tree_parent = new Gee.ArrayList(); + this.tree_children = new Gee.ArrayList(); + 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()); + } + 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 ar) { var ret = new Json.Array(); @@ -912,7 +921,15 @@ namespace JSDOC { } + public Json.Object assocStringToJson( Gee.HashMap> 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 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(); + 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(); + 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(); + 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 = ""; } diff --git a/roojspacker/SymbolSet.vala b/roojspacker/SymbolSet.vala index bf82b2a..c9ec2ae 100644 --- a/roojspacker/SymbolSet.vala +++ b/roojspacker/SymbolSet.vala @@ -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.");