JSDOC/Packer.vala
[gnome.introspection-doc-generator] / JSDOC / Packer.vala
index a9c9442..50e5af9 100644 (file)
@@ -1,16 +1,4 @@
-// <script type="text/javascript">
-const XObject         = imports.XObject.XObject;
-const File            = imports.File.File;
-
-const TextStream      = imports.JSDOC.TextStream.TextStream ;
-const TokenReader     = imports.TokenReader.TokenReader;
-const ScopeParser     = imports.ScopeParser.ScopeParser;
-const TokenStream     = imports.TokenStream.TokenStream;
-const CompressWhite   = imports.CompressWhite.CompressWhite;
-const Collapse        = imports.Collapse.Collapse;
-
-const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
 /**
  * @namespace JSDOC
  * @class  Packer
@@ -22,23 +10,19 @@ const Gio = imports.gi.Gio;
  * Usage:
  * <code>
  *
-Packer = imports['JSDOC/Packer.js'].Packer;
-var x = new  Packer({
-    
-    files : [ "/location/of/file1.js", "/location/of/file2.js", ... ],
-    target : "/tmp/output.js",
-    debugTarget : "/tmp/output.debug.js", // merged file without compression.
-    debugTranslateTarget : "/tmp/output.translate.js", // merged with translation
-                                                       // and no compression
-    translateJSON: "/tmp/translate.json",
-    
+var x = new  JSON.Packer(target, debugTarget);
+
+x.files = an array of files
+x.srcfiles = array of files (that list other files...) << not supported?
+x.target = "output.pathname.js"
+x.debugTarget = "output.pathname.debug.js"
+
+
+x.debugTranslateTarget : "/tmp/output.translate.js" << this used to be the single vs double quotes.. we may not use it in future..
+x.translateJSON: "/tmp/translate.json",
     
-);
-x.packFiles(
-    "/location/of/temp_batch_dir", 
-    "/location/of/output-compacted-file.js",
-    "/location/of/output-debug-merged-file.js"
-);
+x.packAll();  // writes files  etc..
     
  *</code> 
  *
@@ -70,303 +54,296 @@ x.packFiles(
  * 
 
  */
-const Packer = function(cfg)
+namespace JSDOC 
 {
-    
-    XObject.extend(this, cfg);
-    var _this = this;
-    if (this.srcfiles && this.srcfiles.length) {
-        this.srcfiles.forEach(function(f) {
-            _this.loadSourceFile(f);
-        });
-        
-    }
-    
-    if (!this.files) {
-        throw "No Files";
-    }
-    
-    var link = false;
-    if (cfg.autoBuild) {
-        
-        function dateString(d){
-            function pad(n){return n<10 ? '0'+n : n}
-            return d.getFullYear() +
-                 pad(d.getMonth()+1)+
-                 pad(d.getDate())+'_'+
-                 pad(d.getHours())+
-                 pad(d.getMinutes())+
-                 pad(d.getSeconds());
-        }
 
-        
-        
-        var version = 0;
-        this.files.forEach(function(f) {
-            version = Math.max(File.mtime(f), version);
-        });
-        var version  = dateString(new Date(version));
-        
-        var dirname = GLib.path_get_dirname(this.files[0]);
-        var outname = this.module ? this.module : GLib.path_get_basename(dirname);
-        this.target = dirname + '/compiled/' + outname + '-' + version + '.js';
-         if (File.exists(this.target)) {
-            print("Target file already exists: " + this.target);
-            Seed.quit();
-        }
-        this.prefix = dirname +'/';
-        this.translateJSON  = dirname + '/compiled/_translation_.js';
-        
-    }
-     
-    print(this.translateJSON);
-    this.timer =  new Date() * 1;
-    this.packAll();
-    
-    
-    
-}
-Packer.prototype = {
-    /**
-     * @cfg {String} srcfiles file containing a list of files/or classes to use.
-     */
-    srcfile : false,
-    
-    /**
-     * @cfg {Array} files list of files to compress (must be full path)
-     */
-    files : false,
-    /**
-     * @cfg {String} target to write files to - must be full path.
-     */
-    target : '',
-    /**
-     * @cfg {Boolean} autoBuild - turn on autobuild feature (puts files in compiled directory,
-     * and enables translation toolkit.
-     */
-    autoBuild : false,
-     /**
-     * @cfg {String} module used with autoBuild to force a file name
-     */
-    module: false,
-    /**
-     * @cfg {String} debugTarget target to write files debug version to (uncompacted)- must be full path.
-     */
-    debugTarget : '', // merged file without compression.
-    /**
-     * @cfg {String} debugTranslateTarget target to write files debug version
-     *            to (uncompacted) but with translation- must be full path.
-     */
-    
-    debugTranslateTarget : '', 
-    
-    /**
-     * @cfg {String} tmpDir  (optional) where to put the temporary files. 
-     *      if you set this, then files will not be cleaned up
-     */
-    tmpDir : '/tmp',
+
+       public class Packer : Object 
+       {
+               /**
+               * @cfg {String} target to write files to - must be full path.
+               */
+               string target;
+               FileOutputStream targetStream = null;
+               /**
+                * @cfg {String} debugTarget target to write files debug version to (uncompacted)- must be full path.
+                */
+               string targetDebug;
+               
+
+               FileOutputStream targetDebugStream  = null;
+               /**
+                * @cfg {String} tmpDir  (optional) where to put the temporary files. 
+                *      if you set this, then files will not be cleaned up
+                */
+               public string tmpDir = "/tmp";  // FIXME??? in ctor?
+       
+       
+                 
+               /**
+                * @cfg {Boolean} cleanup  (optional) clean up temp files after done - 
+                *    Defaults to false if you set tmpDir, otherwise true.
+                */
+               public bool cleanup =  true;
+               
+               
+               /**
+                * @cfg {Boolean} keepWhite (optional) do not remove white space in output.
+                *    usefull for debugging compressed files.
+                */
+               
+               public bool keepWhite =  true;
+               
+               
+               // list of files to compile...
+               Gee.ArrayList<string> files;
+               
+               public  string out = ""; // if no target is specified - then this will contain the result
     
-    translateJSON : '', // json based list of strings in all files.
+               public Packer(string target, string targetDebug = "")
+               {
+                       this.target = target;
+                       this.targetDebug  = targetDebug;
+               
+               }
+               
+               public void loadSourceIndexes(Gee.ArrayList<string> indexes)
+               {
+                       foreach(var f in indexes) {
+                               this.loadSourceIndex(f);
+                       }
+               }
+               
+               public void loadFiles(Gee.ArrayList<string> fs)
+               {
+                       foreach(var f in fs) {
+                               this.files.add(f); //?? easier way?
+                       }
+               }
+       
+               
+               public void pack()
+               {
+                   if (!this.files) {
+                               throw new Packer.ArgumentError("No Files loaded before pack() called");
+                       }
+                       if (this.target.length > 0 ) {
+                               this.targetStream = File.new_for_path(this.target).replace(null, false,FileCreateFlags.NONE);
+                       }
+                       if (this.targetDebug.length > 0 ) {
+                               this.targetDebugStream = File.new_for_path(this.targetDebug).replace(null, false,FileCreateFlags.NONE);
+                       }
+                       this.packAll();
+               }
+               
+  
+               
+               
    
-    /**
-     * @cfg {Boolean} cleanup  (optional) clean up temp files after done - 
-     *    Defaults to false if you set tmpDir, otherwise true.
-     */
-    cleanup : true,  
-    /**
-     * @cfg {Boolean} keepWhite (optional) do not remove white space in output.
-     *    usefull for debugging compressed files.
-     */
-    
-    keepWhite: true,
-    
-    /**
-     * @cfg {String} prefix (optional) prefix of directory to be stripped of when
-     *    Calculating md5 of filename 
-     */
-    prefix : '',  
-    out : '', // if no target is specified - then this will contain the result
-    
-    /**
-     * load a dependancy list -f option
-     * @param {String} srcfile sourcefile to parse
-     * 
-     */
-    
-    loadSourceFile : function(srcfile)
-    {
-        var lines = File.read(srcfile).split("\n");
-        var _this = this;
-        lines.forEach(function(f) {
-            
-            if (/^\s*\//.test(f) || !/[a-z]+/i.test(f)) { // skip comments..
-                return;
-            }
-            if (/\.js$/.test(f)) {
-                _this.files.push( f);
-                // js file..
-                return;
-            }
-            
-            //println("ADD"+ f.replace(/\./g, '/'));
-            var add = f.replace(/\./g, '/').replace(/\s+/g,'')+'.js';
-            if (_this.files.indexOf(f) > -1) {
-                return;
-            }
-            _this.files.push( add );
-            
-        })
-    },
-    
-    
-    packAll : function()  // do the packing (run from constructor)
-    {
-        
-        //this.transOrigFile= bpath + '/../lang.en.js'; // needs better naming...
-        //File.write(this.transfile, "");
-        if (this.target) {
-            File.write(this.target, "");
-        }
-        
-        if (this.debugTarget) {
-            File.write(this.debugTarget, "");
-        }
-        if (this.debugTranslateTarget) {
-            File.write(this.debugTarget, "");
-        }
-        
-        for(var i=0; i < this.files.length; i++)  {
-            var file = this.files[i];
-            
-            print("reading " +file );
-            if (!File.isFile(file)) {
-                print("SKIP (is not a file) " + file);
-                continue;
-            }
-           
-            // debug Target
-            
-            if (this.debugTarget) {
-                File.append(this.debugTarget, File.read(file));
-            }
-            // it's a good idea to check with 0 compression to see if the code can parse!!
-            
-            // debug file..
-            //File.append(dout, str +"\n"); 
-            
-       
-            
-            var minfile = this.tmpDir + '/' +file.replace(/\//g, '.');
-            
-            
-            // let's see if we have a min file already?
-            // this might happen if tmpDir is set .. 
-            if (true && File.exists(minfile)) {
-                var mt = File.mtime(minfile);
-                var ot = File.mtime(file);
-                print("compare : " + mt + "=>" + ot);
-                if (mt >= ot) {
-                    continue;
-                    
-                }
-                
-            }
-             
-            print("COMPRESSING ");
-            //var codeComp = pack(str, 10, 0, 0);
-            if (File.exists(minfile)) {
-                File.remove(minfile);
-            }
-            var str = File.read(file);
-            var str = this.pack(str, file, minfile);
-             
-          
-        }
-        
-        
-        
-        // if we are translating, write the translations strings at the top
-        // of the file..
-        
-        if (this.translateJSON) {
-            
-               
-            print("MERGING LANGUAGE");
-            var out = "if (typeof(_T) == 'undefined') { _T={};}\n"
-            if (this.target) {
-                File.write(this.target, out);
-            } else {
-                this.out += out;
-            }
-             
-            File.write(this.translateJSON, "");
-            for(var i=0; i < this.files.length; i++)  {
-                var file = this.files[i];
-                var transfile= this.tmpDir + '/' +file.replace(/\//g, '.') +'.lang.trans';
-                var transmd5 = this.tmpDir  + '/' +file.replace(/\//g, '.') +'.lang';
-                if (File.exists(transmd5)) {
-                    var str = File.read(transmd5);
-                    if (str.length) {
-                        if (this.target) {
-                            File.append(this.target, str + "\n");
-                        } else {
-                            this.out += str + "\n";
-                        }
-                        
-                    }
-                    if (this.cleanup) {
-                        File.remove(transmd5);
-                    }
-                }
-                if (File.exists(transfile)) {
-                    var str = File.read(transfile);
-                    if (str.length) {
-                        File.append(this.translateJSON, str);
-                    }
-                    if (this.cleanup) {
-                        File.remove(transfile);
-                    }
-                }
-                
-               
-            }
-        }
-        
-        print("MERGING SOURCE");
-        
-        for(var i=0; i < this.files.length; i++)  {
-            var file = this.files[i];
-            var minfile = this.tmpDir + '/' + file.replace(/\//g, '.');
-            
-            
-            if (!File.exists(minfile)) {
-                continue;
-            }
-            var str = File.read(minfile);
-            print("using MIN FILE  "+ minfile);
-            if (str.length) {
-                if (this.target) {
-                    File.append(this.target, '//' + file + "\n");   
-                    File.append(this.target, str + "\n");   
-                } else {
-                    this.out += '//' + file + "\n";
-                    this.out += str + "\n";
-                }
-                
-            }
-            if (this.cleanup) {
-                File.remove(minfile);
-            }
-            
-        }
-        print("Output file: " + this.target);
-        if (this.debugTarget) print("Output debug file: " + this.debugTarget);
-        
-         
-    
+               
+          
+               /**
+                * load a dependancy list -f option
+                * @param {String} srcfile sourcefile to parse
+                * 
+                */
+               
+               public void loadSourceIndex(string srcfile)
+               {
+                   string str;
+                   FileUtils.get_contents(srcfile,out str);
+                   
+                   var lines = str.split("\n");
+                   for(var i =0; i < lines.length;i++) {
+                           var f = lines[i].strip();
+                       if (f.length < 1 ||
+                               Regex.match_simple ("^/", f) ||
+                               !Regex.match_simple ("[a-zA-Z]+", f) 
+                       ){
+                               continue; // blank comment or not starting with a-z
+                       }
+                       
+                       if (Regex.match_simple ("\\.js$", f)) {
+                           this.files.add( f);
+                           // js file..
+                           continue;
+                       }
+                       
+                               // this maps Roo.bootstrap.XXX to Roo/bootstrap/xxx.js
+                               // should we prefix? =- or should this be done elsewhere?
+                               
+                       var add = f.replace(".", "/") + ".js";
+                       if (_this.files.contains(add)) {
+                           continue;
+                       }
+                       _this.files.add( add );
+                       
+                   }
+               }
+               
     
-    },
+               private void packAll()  // do the packing (run from constructor)
+               {
+                   
+                   //this.transOrigFile= bpath + '/../lang.en.js'; // needs better naming...
+                   //File.write(this.transfile, "");
+                   if (this.target.length > 0) {
+                       this.targetStream.write("");
+                   }
+                   
+                   if (this.debugTarget > 0) {
+                           this.targetDebugStream.write("");
+                   }
+                   foreach(var file in this.files) {
+                       
+                       print("reading %s\n",file );
+                       
+                       if (FileUtils.test (file, FileTest.EXISTS) && ! FileUtils.test (file, FileTest.IS_DIR)) {
+                           print("SKIP (is not a file) %s\n ", file);
+                           continue;
+                       }
+                      
+                               var loaded_string = false;
+                               string file_contents;
+                       // debug Target
+                       
+                       if (this.targetDebugStream !=null) {
+                               
+                               FileUtils.get_contents(file,out file_contents);
+                           this.targetDebugStream.write(file_contents);
+                           loaded_string = false;
+                       }
+                       // it's a good idea to check with 0 compression to see if the code can parse!!
+                       
+                       // debug file..
+                       //File.append(dout, str +"\n"); 
+                       
+                  
+                       
+                       var minfile = this.tmpDir + '/' + file.replace("/", '.');
+                       
+                       
+                       // let's see if we have a min file already?
+                       // this might happen if tmpDir is set .. 
+
+                       
+                       if (true && FileUtils.test (minfile, FileTest.EXISTS)) {
+                               
+                               var otv = File.new_for_path(file).query_info (FileAttribute.TIME_MODIFIED, 0).get_modification_time();
+                               var mtv = File.new_for_path(minfile).query_info (FileAttribute.TIME_MODIFIED, 0).get_modification_time();
+                                       
+                                       var ot = new Date();
+                                       ot.set_time_val(otv);
+                                       var mt = new Date();
+                                       mt.set_time_val(mtv);
+                           //print("compare : " + mt + "=>" + ot);
+                           if (mt.compare(ot) >= 0) {
+                               continue; // file is newer or the same time..
+                               
+                           }
+                           
+                       }
+                        
+                       print("COMPRESSING ");
+                       //var codeComp = pack(str, 10, 0, 0);
+                       if (FileUtils.test (minfile, FileTest.EXISTS)) {
+                           FileUtils.remove(minfile);
+                       }
+                       if (!loaded_string) {
+                               FileUtils.get_contents(file,out file_contents);
+                       }
+
+                       var str = this.packFile(file_contents, file, minfile);
+                        
+                     
+                   }
+                   
+                   
+                   
+                   // if we are translating, write the translations strings at the top
+                   // of the file..
+                   /*
+                   if (this.translateJSON) {
+                       
+                          
+                       print("MERGING LANGUAGE");
+                       var out = "if (typeof(_T) == 'undefined') { _T={};}\n";
+                       if (this.target) {
+                           File.write(this.target, out);
+                       } else {
+                           this.out += out;
+                       }
+                        
+                       File.write(this.translateJSON, "");
+                       for(var i=0; i < this.files.length; i++)  {
+                           var file = this.files[i];
+                           var transfile= this.tmpDir + '/' +file.replace(/\//g, '.') +'.lang.trans';
+                           var transmd5 = this.tmpDir  + '/' +file.replace(/\//g, '.') +'.lang';
+                           if (File.exists(transmd5)) {
+                               var str = File.read(transmd5);
+                               if (str.length) {
+                                   if (this.target) {
+                                       File.append(this.target, str + "\n");
+                                   } else {
+                                       this.out += str + "\n";
+                                   }
+                                   
+                               }
+                               if (this.cleanup) {
+                                   File.remove(transmd5);
+                               }
+                           }
+                           if (File.exists(transfile)) {
+                               var str = File.read(transfile);
+                               if (str.length) {
+                                   File.append(this.translateJSON, str);
+                               }
+                               if (this.cleanup) {
+                                   File.remove(transfile);
+                               }
+                           }
+                           
+                          
+                       }
+                   }
+                   */
+                   print("MERGING SOURCE");
+                   
+                   for(var i=0; i < this.files.length; i++)  {
+                       var file = this.files[i];
+                       var minfile = this.tmpDir + '/' + file.replace('/', '.');
+                       
+                       
+                       if (!File.exists(minfile)) {
+                           continue;
+                       }
+                       var str = File.read(minfile);
+                       print("using MIN FILE  "+ minfile);
+                       if (str.length) {
+                           if (this.targetStream != null) {
+                                       this.targetStream.write("//" + file + "\n"); 
+                                       this.targetStream.write(str + "\n"); 
+
+                           } else {
+                               this.out += "//" + file + "\n";
+                               this.out += str + "\n";
+                           }
+                           
+                       }
+                       if (this.cleanup) {
+                           FileUtils.remove(minfile);
+                       }
+                       
+                   }
+                   print("Output file: " + this.target);
+                   if (this.debugTarget) print("Output debug file: " + this.debugTarget);
+                   
+                    
+               
+               
+               }
     /**
      * Core packing routine  for a file
      * 
@@ -376,7 +353,7 @@ Packer.prototype = {
      * 
      */
     
-    pack : function (str,fn,minfile)
+    void packFile  (string str,string fn, string minfile)
     {
     
         var tr = new  TokenReader(  { 
@@ -434,172 +411,16 @@ Packer.prototype = {
         
          
     },
+     
     
-    timerPrint: function (str) {
-        var ntime = new Date() * 1;
-        var tdif =  ntime -this.timer;
-        this.timer = ntime;
-        print('['+tdif+']'+str);
-    },
-    
-    /**
-     * 
-     * Translation concept...
-     * -> replace text strings with _T....
-     * -> this file will need inserting at the start of the application....
-     * -> we need to generate 2 files, 
-     * -> a reference used to do the translation, and the _T file..
-     *
-     *
-     * We store the trsum on the token...
-     * 
-     */
-    
-    writeTranslateFile : function(fn, minfile, toks) 
-    {
-        
-        var map = {};  // 'string=> md5sum'
-        var _this = this;
-        var t, last, next;
-        
-        
-        var tokfind =  function (j,dir) {
-            while (1) {
-                if ((dir < 0) && (j < 0)) {
-                    return false;
-                }
-                if ((dir > 0) && (j >= toks.length)) {
-                    return false;
-                }
-                j += dir;
-                if (toks[j].type != 'WHIT') {
-                    return toks[j];
-                }
-            }
-            return false;
-            
-        }
-        
-        
-        for (var i=0;i<toks.length;i++) {
-            
-            t = toks[i];
-            if (t.type != 'STRN') {
-                continue;
-            }
-            if (t.name != 'DOUBLE_QUOTE') {
-                continue;
-            }
-            
-            last = tokfind(i,-1);
-            next = tokfind(i,+1);
-            
-            // we have to ignore key values on objects
-            
-            // defined by
-            // last == '{' or ',' and
-            // next == ':'
-            
-            if (next &&
-                next.type == 'PUNC' &&
-                next.data == ':' && 
-                last && 
-                last.type == 'PUNC' &&
-                (last.data == ',' || last.data == '{')
-            ){
-                continue; // found object key... - we can not translate these
-            }
-                
-            var sval = t.data.substring(1,t.data.length-1);
-            var ffn = fn.substring(_this.prefix.length);
-            
-            t.trsum = _this.md5(ffn + '-' + sval);
-            map[sval] = t.trsum;
-            
-            
-            
-        }
-        
-        
-        var transfile = minfile + '.lang.trans';
-        var transmd5 = minfile + '.lang';
-        print("writeTranslateFile "  + transfile);
-        var i = 0;
-        var v = '';
-        if (File.exists(transfile)) {
-            File.remove(transfile);
-        }
-        if (File.exists(transmd5)) {
-            File.remove(transmd5);
-        }
-        for(v in map) { i++; break };
-        if (!i ) {
-            return; // no strings in file...
-        }
-        var ffn = fn.substring(this.prefix.length);
-         
-         
-        File.write(transfile, "\n'" + ffn  + "' : {");
-        var l = '';
-        var _tout = {}
-         
-        File.write(transmd5, '');
-        for(v in map) {
-            if (!v.length) {
-                continue;
-            }
-            File.append(transfile, l + "\n\t\"" + v  + "\" : \"" + v +"\"");
-            l = ',';
-            // strings are raw... - as the where encoded to start with!!!
-            // so we should not need to encode them again.. - just wrap with "
-            File.append(transmd5, '_T["' + this.md5(ffn + '-' + v) + '"]="'+v+"\";\n");
-        }
-        File.append(transfile, "\n},"); // always one trailing..
-        
-         
-    },
     md5 : function (string)
     {
         
         return GLib.compute_checksum_for_string(GLib.ChecksumType.MD5, string, string.length);
         
     },
-    stringHandler : function(tok)
-    {
-        //print("STRING HANDLER");
-       // callback when outputing compressed file, 
-       var data = tok.data;
-        if (!this.translateJSON) {
-         //   print("TURNED OFF");
-            return data;
-        }
-        if (tok.name == 'SINGLE_QUOTE') {
-            return data;
-        }
-        
-        if (typeof(tok.trsum) == 'undefined') {
-            return data;
-        }
-        
-        return '_T["' + tok.trsum + '"]';
-        
-        var sval = data.substring(1,data.length-1);
-        // we do not clean up... quoting here!??!!?!?!?!?
-        
-        
-        // blank with tabs or spaces..
-        //if (!sval.replace(new RegExp("(\\\\n|\\\\t| )+",'g'), '').length) {
-       //     return tok.outData;
-       // }
-        
-        var sval = tok.data.substring(1,data.length-1);
-        var fn = this.activeFile.substring(this.prefix.length);
-        
-        
-        return '_T["' + this.md5(fn + '-' + sval) + '"]';
-        
-        
-    }
+    
+    //stringHandler : function(tok) -- not used...
     
     
 };