namespace JSDOC { class DocBuilder : Object { // extractable via JSON? public string VERSION = "1.0.0" ; private Packer packer; public DocBuilder (Packer p) { DocBuilder.init(); GLib.debug("Roo JsDoc Toolkit started at %s ", (new GLib.DateTime()).format("Y/m/d H:i:s")); this.packer = p; if (PackerRun.opt_tmp_dir != null && !FileUtils.test(PackerRun.opt_tmp_dir, GLib.FileTest.IS_DIR)) { Posix.mkdir(PackerRun.opt_tmp_dir, 0700); } this.parseSrcFiles(); this.symbolSet = DocParser.symbols; // this currently uses the concept of publish.js... this.publish(); } static bool done_init = false; static GLib.Regex regex_dotdot; static void init() { if (done_init) { return; } // ./ or ../ DocBuilder.regex_dotdot = new Regex("\\\\.\\\\.?[/]"); } /** * Parse the source files. * */ private void parseSrcFiles() { DocParser.init(); var useCache = PackerRun.opt_cache_dir == null ; var cacheFile = ""; for (var i = 0, l = this.packer.files.size; i < l; i++) { var srcFile = this.packer.files.get(i); if (useCache) { cacheFile = PackerRun.opt_cache_dir + srcFile.replace("/", '_') + ".cache"; //print(cacheFile); // disabled at present!@!! if (GLib.FileUtils.test(cacheFile, GLib.FileTest.EXISTS)) { // check filetime? var cache_mt = File.new_for_path (cacheFile).queryInfo(FileAttribute.TIME_MODIFIED, GLib.FileQueryInfoFlags.NONE, null). get_modification_time(); var original_mt = File.new_for_path (sourceInfo).queryInfo(FileAttribute.TIME_MODIFIED, GLib.FileQueryInfoFlags.NONE, null). get_modification_time(); // this check does not appear to work according to the doc's - need to check it out. if (cache_mt > original_mt) { // cached time > original time! // use the cached mtimes.. GLib.debug("Read %s" , cacheFile); var parser = new Json.Parser(); parser.load_from_file(cacheFile); var ar = parser.get_root ().get_array(); for(var i = 0;i < ar.get_length();i++) { var o = ar.get_object_element(i); var sym = JSON.gobject_from_data(typeof(Symbol), o) as Symbol; DocParser.symbols.add(sym); } continue; } } } var src = ""; try { GLib.debug("reading : %s" , srcFile); src = GLib.FileUtils.get_contents(srcFile); } catch(GLib.FileError e) { GLib.debug("Can't read source file '%s': %s", srcFile, e.to_string()); continue; } var tr = new TokenReader(this.packer); tr.keepDocs = true; tr.keepWhite = true; tr.keepComments = true; tr.sepIdents = false; tr.collapseWhite = false; tr.filename = src; 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(); foreach(var symbol in symbols) { if (symbol.isaClass()) { classes.add(symbol); } } classes.sort( (a,b) => { return a.alias.collate(b.alias); }); //GLib.debug("classTemplate Process : all classes"); // var classesIndex = classesTemplate.process(classes); // kept in memory GLib.debug("iterate classes"); var jsonAll = new JSON.Object(); for (var i = 0, l = classes.size; i < l; i++) { var symbol = classes.get(i); var output = ""; GLib.debug("classTemplate Process : %s" , symbol.alias); FileUtils.set_contents( PackerRun.opt_doc_target+"/symbols/" +symbol.alias+'.' + PackerRun.opt_doc_ext , classTemplate.process(symbol) ); jsonAll.set_object_member(symbol.alias, this.publishJSON(symbol)); } Json.Generator generator = new Json.Generator (); generator.set_root (jsonAll.get_node()); generator.pretty= true; generator.ident = 2; generator.to_file(PackerRun.opt_doc_target+"/json/roodata.json"); // regenrate the index with different relative links Link.base = ""; //var classesIndex = classesTemplate.process(classes); GLib.debug("build index"); FileUtils.set_contents( PackerRun.opt_doc_target + "/index." + PackerRun.opt_doc_ext , classesindexTemplate.process(classes) ); // blank everything???? classesindexTemplate = classesIndex = classes = null; /* var documentedFiles = symbols.filter(function ($) { return ($.is("FILE")) }); var allFiles = []; for (var i = 0; i < files.length; i++) { allFiles.push(new Symbol(files[i], [], "FILE", new DocComment("/** *" + "/"))); } for (var i = 0; i < documentedFiles.length; i++) { var offset = files.indexOf(documentedFiles[i].alias); allFiles[offset] = documentedFiles[i]; } allFiles = allFiles.sort(makeSortby("name")); GLib.debug("write files index"); FileUtils.set_contents( PackerRun.opt_doc_target + "/files." + PackerRun.opt_doc_ext , fileindexTemplate.process(allFiles) ); */ } /** * 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 GLib.ArrayList(); if (!data.comment.getTag(DocTagTitle.SINGLETON).length) { cfgProperties = data.configToArray(); cfgProperties = cfgProperties.sort((a,b) =>{ return a.alias.collate(b.alias); }); } var props = new JSON.Array();; //println(cfgProperties.toSource()); for(var i =0; i < cfgProperties.size;i++) { var p = cfgPropertiesget.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) { add.set_array_member("desc",p.optvalues_as_json_array()); } props.add_object(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.comment.getTag(DocTagTitle.HIDE) == "") { 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,m.name.length-1)); add.set_string_member("type","function"); add.set_string_member("desc",m.desc); add.set_string_member("sig", this.makeFuncSkel(m.params)); events.add(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.comment.getTag(DocTagTitle.HIDE) == "") { 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.substring(1,m.name.length-1)); add.set_string_member("type","function"); add.set_string_member("desc",m.desc); add.set_string_member("sig", this.makeMethodSkel(m.params)); events.add(add); } //println(props.toSource()); // we need to output: //classname => { // propname => // type=> // desc=> // } var ret = new JSON.Object(); ret.set_object_member("props", props); ret.set_object_member("events", events); ret.set_object_member("methods", methods); return ret; // b) methods // c) events } // in Link (js) ??? string srcFileRelName(string sourceFile) { return sourceFile.substring(PackerRun.opt_real_basedir.length+1); } string srcFileFlatName(string sourceFile) { var name = this.srcFileRelName(sourceFile); name = DocBuilder.regex_dotdot.replace(name, name.length, 0, ""); name = name.replace("/", "_").replace(":", "_") + ".html"; } void makeSrcFile(string sourceFile) { // this stuff works... var name = this.srcFileFlatName(sourceFile); GLib.debug("Write Source file : %s/symbols/src/%s", opt_doc_target, name); var pretty = PrettyPrint.toPretty(FileUtils.get_contenst(sourceFile)); File.write(PackerRun.opt_doc_target+"/symbols/src/" + name, "" + "" + sourceFile + "" + "" + "" + pretty + ""); } /** * used by JSON output to generate a function skeleton */ /* string makeFuncSkel(Gee.ArrayList params) { if (params.length < 0) { return "function ()\n{\n\n}"; } return "function (" + params.filter( function($) { return $.name.indexOf(".") == -1; // don't show config params in signature } ).map( function($) { return $.name == 'this' ? '_self' : $.name; } ).join(", ") + ")\n{\n\n}"; }, makeMethodSkel :function(params) { if (!params) return "()"; return "(" + params.filter( function($) { return $.name.indexOf(".") == -1; // don't show config params in signature } ).map( function($) { return $.type + " " +( $.name == 'this' ? '_self' : $.name ); } ).join(", ") + ")"; } */ } }