Re-arrange files, add support for classic JS Documentor, and packer origin/HEAD origin/master
authorAlan Knowles <alan@akbkhome.com>
Fri, 23 Jul 2010 00:02:54 +0000 (08:02 +0800)
committerAlan Knowles <alan@akbkhome.com>
Fri, 23 Jul 2010 00:02:54 +0000 (08:02 +0800)
Major overhall of the codebase, including
- Move to use glib head (some methods are renamed)
- Javascript Packer runs and is working
- Javascript Code Documentor is now running and working (mostly)
- Code layout changed to better issolate usage
 * Introspect now a top level directory (for all the gir related code)
 * JsTemplate now a top level directory (for the rendering / view layer)
 * JSDOC now contains only the packer and js code documentor

63 files changed:
Date.js
File.js
Introspect/Base.js [moved from JSDOC/Introspect/Base.js with 93% similarity]
Introspect/Basic.js [moved from JSDOC/Introspect/Basic.js with 95% similarity]
Introspect/Callback.js [moved from JSDOC/Introspect/Callback.js with 74% similarity]
Introspect/Class.js [moved from JSDOC/Introspect/Class.js with 92% similarity]
Introspect/Constant.js [moved from JSDOC/Introspect/Constant.js with 78% similarity]
Introspect/Enum.js [moved from JSDOC/Introspect/Enum.js with 80% similarity]
Introspect/Field.js [moved from JSDOC/Introspect/Field.js with 72% similarity]
Introspect/Interface.js [moved from JSDOC/Introspect/Interface.js with 70% similarity]
Introspect/Link.js [new file with mode: 0644]
Introspect/Method.js [moved from JSDOC/Introspect/Method.js with 79% similarity]
Introspect/NameSpace.js [moved from JSDOC/Introspect.js with 93% similarity]
Introspect/Property.js [moved from JSDOC/Introspect/Property.js with 61% similarity]
Introspect/Signal.js [moved from JSDOC/Introspect/Signal.js with 75% similarity]
Introspect/Struct.js [moved from JSDOC/Introspect/Struct.js with 85% similarity]
Introspect/Union.js [moved from JSDOC/Introspect/Union.js with 84% similarity]
Introspect/extensions/xml.js [moved from JSDOC/Introspect/extensions/xml.js with 100% similarity]
JSDOC.js [deleted file]
JSDOC/BuildDocs.js [new file with mode: 0644]
JSDOC/Collapse.js
JSDOC/CompressWhite.js
JSDOC/DocComment.js [new file with mode: 0644]
JSDOC/DocTag.js [new file with mode: 0644]
JSDOC/GtkFile.js
JSDOC/Lang.js
JSDOC/Options.js [new file with mode: 0644]
JSDOC/Packer.js
JSDOC/Parser.js [new file with mode: 0644]
JSDOC/PrettyPrint.js [new file with mode: 0644]
JSDOC/RooFile.js
JSDOC/Scope.js
JSDOC/ScopeParser.js
JSDOC/Symbol.js [new file with mode: 0644]
JSDOC/SymbolSet.js [new file with mode: 0644]
JSDOC/Template.js [deleted file]
JSDOC/Template/Link.js [deleted file]
JSDOC/TextStream.js
JSDOC/Token.js
JSDOC/TokenReader.js
JSDOC/TokenStream.js
JSDOC/Walker2.js [new file with mode: 0644]
JsTemplate/Link.js [new file with mode: 0644]
JsTemplate/Template.js [new file with mode: 0644]
Object.js [deleted file]
README.txt
String.js
XObject.js
docs.js
docs/build_docs.sh [deleted file]
jhbuild.js
jsdocbuild.js [new file with mode: 0644]
pack.js
rebuild_typelibs.sh [new file with mode: 0644]
templates/resources/default.css [moved from docs/resources/default.css with 100% similarity, mode: 0644]
templates/resources/library_gnome.css [moved from docs/resources/library_gnome.css with 100% similarity, mode: 0644]
templates/resources/library_gnome_print.css [moved from docs/resources/library_gnome_print.css with 100% similarity, mode: 0644]
templates/resources/page.js [moved from docs/resources/page.js with 100% similarity, mode: 0644]
templates/seed/class.html [moved from docs/class.html with 100% similarity]
templates/seed/class_ix.html [moved from docs/class_ix.html with 100% similarity, mode: 0644]
templates/seed/index.html [moved from docs/index.html with 100% similarity, mode: 0644]
templates/seed/references.html [moved from docs/references.html with 100% similarity]
xnew.js [deleted file]

diff --git a/Date.js b/Date.js
index bbbd93a..ceb5292 100755 (executable)
--- a/Date.js
+++ b/Date.js
@@ -8,18 +8,11 @@
  * Fork - LGPL
  * <script type="text/javascript">
  */
+// usage: Seed.include('Date.js')
 
-//imports['Date.js'].load(Date);
-if (imports) {
-    imports['String.js'].load(String);
 
-}
-
-if (imports) {
-    load = false; // declare global for gnome langs.
-}
-(function() {
+String          = imports.String.String;
+XObject         = imports.XObject.XObject;
 
 
 /**
@@ -119,7 +112,8 @@ document.write(dt.format(Date.patterns.ShortDate));
      @return {Number} The diff in milliseconds
      @member Date getElapsed
      */
-    var date = {
+Date = XObject.extend(Date,
+    {
         
         // private
         parseFunctions : {count:0},
@@ -336,7 +330,9 @@ document.write(dt.format(Date.patterns.ShortDate));
             return Date[func](input);
         },
 
-        // private
+        /**
+        * @private
+        */
         createParser : function(format) {
             var funcName = "parse" + Date.parseFunctions.count++;
             var regexNum = Date.parseRegexes.length;
@@ -523,9 +519,12 @@ document.write(dt.format(Date.patterns.ShortDate));
         }
 
         
-    };
+    
+}); // end static date..
 
-    var datePrototype = {
+// now add functions to date..
+XObject.extend(Date.prototype,
+    {
 
         getElapsed : function(date) {
             return Math.abs((date || new Date()).getTime()-this.getTime());
@@ -785,25 +784,5 @@ document.write(dt.format(Date.patterns.ShortDate));
           }
           return d;
         }
-    };
-    if (imports) {
-        load = function(ar) {
-            Date = ar;
-            imports.lang.copyPropertiesNoOverwrite( date,ar);
-            imports.lang.copyPropertiesNoOverwrite(datePrototype, ar.prototype);
-            
-        };
-    } else {
-        // non imports version.
-        for(i in datePrototype) {
-            if (!Date.prototype[i]) {
-                Date.prototype[i] = datePrototype[i];
-            }
-        }
-        for(i in date) {
-            if (!Date[i]) {
-                Date[i] = date[i];
-            }
-        }
-    }
-})();
\ No newline at end of file
+
+});
\ No newline at end of file
diff --git a/File.js b/File.js
index a704c9e..77777ba 100755 (executable)
--- a/File.js
+++ b/File.js
@@ -2,8 +2,7 @@
 GLib = imports.gi.GLib;
 Gio = imports.gi.Gio;
 
-imports['String.js'].load(String);
-
+String  = imports.String.String; 
 /**
 * @namespace File
 * 
@@ -174,6 +173,7 @@ var File = {
      */
     mkdir : function (destPath) {
         var dest = Gio.file_new_for_path(String(destPath));
+        
         return dest.make_directory(null, null);
     },
     /**
similarity index 93%
rename from JSDOC/Introspect/Base.js
rename to Introspect/Base.js
index 8a2bd26..9876fb5 100644 (file)
@@ -5,12 +5,11 @@ GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 //GObject = imports.gi.GObject;
 
-imports['Object.js'].load(Object);
+XObject = imports.XObject.XObject;
+console = imports.console.console;
 
-console = imports['console.js'].console;
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
+NameSpace = imports.NameSpace.NameSpace;
+Basic = imports.Basic.Basic;
 
 
 
@@ -22,7 +21,7 @@ Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
 
 
  
-Base = Object.define(
+Base = XObject.define(
    function(ns, name) {
         // fake should not happen?
         
@@ -53,7 +52,7 @@ Base = Object.define(
         this.implementedBy = []; // interface - which object uses it.
         this.extendsClasses = []; // what it extends...
         this.childClasses = []; // what 
-         this.desc = Introspect.doc(this.alias );
+         this.desc = NameSpace.doc(this.alias );
         
         
         var gi = GI.IRepository.get_default();
@@ -106,7 +105,8 @@ Base = Object.define(
             var bb = this.getBI();
             var _this = this;
            //console.log("ADD " + type[0].toUpperCase() + type.substring(1));
-            var cls = Introspect[type[0].toUpperCase() + type.substring(1)]; // ucfirst.
+            var clname = type[0].toUpperCase() + type.substring(1);
+            var cls = imports[clname][clname];
             if (!cls) {
                 console.log("COULD NOT FIND Introspect: " + type[0].toUpperCase() + type.substring(1));
                }
similarity index 95%
rename from JSDOC/Introspect/Basic.js
rename to Introspect/Basic.js
index 43c723f..50f58b9 100644 (file)
@@ -4,10 +4,9 @@ GI      = imports.gi.GIRepository;
 GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 //GObject = imports.gi.GObject;
-imports['Object.js'].load(Object);
 
-console     = imports['console.js'].console;
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
+XObject = imports.XObject.XObject;
+console = imports.console.console;
 
 
 
@@ -16,7 +15,7 @@ Introspect = imports['JSDOC/Introspect.js'].Introspect;
  */
 
 
-Basic = Object.define(
+Basic = XObject.define(
     function( ) {
          // never called?
     },
@@ -47,7 +46,7 @@ Basic = Object.define(
             var interface_type = GI.base_info_get_type (interface_info);
             if (interface_type  == GI.IInfoType.CALLBACK) {
                 // callback.. 
-                var Callback = Introspect.Callback ;
+                var Callback = imports.Callback.Callback ;
                 var ret=  new Callback(interface_info, this, false, false);
                 ret.alias = GI.base_info_get_namespace(interface_info) + '.' + GI.base_info_get_name(interface_info);
                 return ret;
similarity index 74%
rename from JSDOC/Introspect/Callback.js
rename to Introspect/Callback.js
index f92f466..d9a7318 100644 (file)
@@ -4,16 +4,17 @@ GI      = imports.gi.GIRepository;
 GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 //GObject = imports.gi.GObject;
-imports['Object.js'].load(Object);
 
-console = imports['console.js'].console;
+XObject = imports.XObject.XObject;
+console = imports.console.console;
 
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
 
+NameSpace = imports.NameSpace.NameSpace;
+Basic = imports.Basic.Basic;
 
 
-Callback = Object.define(
+
+Callback = XObject.define(
     function(sig, memberOf, saveto, keylist) {
 
         
@@ -28,7 +29,7 @@ Callback = Object.define(
         });
         */
         
-        Object.extend(this,{
+        XObject.extend(this,{
             name : GI.base_info_get_name(sig),
             params : params,
             //memberOf : memberOf.alias,
@@ -36,7 +37,7 @@ Callback = Object.define(
             returns :   [ { type :  this.typeToName(GI.callable_info_get_return_type(sig)) } ]            
             
         });
-        this.desc =  Introspect.doc(memberOf.alias + '.' + this.name);
+        this.desc =  NameSpace.doc(memberOf.alias + '.' + this.name);
         //memberOf[saveto].push(this);
         //keylist.push(this.name);
         
similarity index 92%
rename from JSDOC/Introspect/Class.js
rename to Introspect/Class.js
index 08a103b..dba5f90 100644 (file)
@@ -4,14 +4,13 @@ GI      = imports.gi.GIRepository;
 GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 //GObject = imports.gi.GObject;
-imports['Object.js'].load(Object);
+XObject = imports.XObject.XObject;
+console = imports.console.console;
+NameSpace = imports.NameSpace.NameSpace;
 
-console = imports['console.js'].console;
-
-
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Base = imports['JSDOC/Introspect/Base.js'].Base;
+Base = imports.Base.Base;
 
 
 
@@ -23,7 +22,7 @@ Base = imports['JSDOC/Introspect/Base.js'].Base;
 
 
 
-Class = Object.define(
+Class = XObject.define(
     function(ns, name) {
         Base.call(this, ns, name);
         this.loadExtends();
@@ -43,7 +42,7 @@ Class = Object.define(
             if (!pi) {
                 return;
             }
-            this.parent = Introspect.factory(
+            this.parent = NameSpace.factory(
                 'Class',
                 GI.base_info_get_namespace(pi),
                 GI.base_info_get_name(pi)
@@ -70,7 +69,7 @@ Class = Object.define(
                 var prop = GI.object_info_get_interface(bb,i);
                  
                 
-                var iface = Introspect.factory(
+                var iface = NameSpace.factory(
                     'Interface', 
                     GI.base_info_get_namespace(prop) , GI.base_info_get_name(prop)
                 );
@@ -136,7 +135,7 @@ Class = Object.define(
             this.genericImplements( signals, 'signals');    
             
             
-            Introspect.references[this.alias] = Introspect.references[this.alias] || [];
+            NameSpace.references[this.alias] = NameSpace.references[this.alias] || [];
             if (this.alias == 'GObject.Object') {
                 this._loaded = true;
                 return;
similarity index 78%
rename from JSDOC/Introspect/Constant.js
rename to Introspect/Constant.js
index bc64386..bad3f6d 100644 (file)
@@ -4,23 +4,22 @@ GI      = imports.gi.GIRepository;
 GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 
-imports['Object.js'].load(Object);
 
-console = imports['console.js'].console;
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
+Basic        = imports.Basic.Basic;
 
-
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
-
 
 /**
  * Constant
  */
 
 
-Constant = Object.define(
+Constant = XObject.define(
     function(prop, memberOf, saveto, keylist) {
           
         this.name  =  GI.base_info_get_name(prop);
@@ -45,7 +44,7 @@ Constant = Object.define(
             }
         } 
         
-        this.desc = Introspect.doc(memberOf.alias + '.' + this.name)
+        this.desc = NameSpace.doc(memberOf.alias + '.' + this.name)
         
         memberOf[saveto].push(this);
         keylist.push(this.name);
similarity index 80%
rename from JSDOC/Introspect/Enum.js
rename to Introspect/Enum.js
index 379b3ad..1dddc21 100644 (file)
@@ -5,21 +5,20 @@ GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 
 
-imports['Object.js'].load(Object);
 
-console = imports['console.js'].console;
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
+Base        = imports.Base.Base;
 
+  
 
 
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Base = imports['JSDOC/Introspect/Base.js'].Base;
 
 
-
-
-
-Enum = Object.define(
+Enum = XObject.define(
     function(ns, name) {
         Base.call(this, ns, name);
     },
@@ -33,7 +32,7 @@ Enum = Object.define(
                 return; // already loaded..
             }
             
-            this.desc = Introspect.doc(this.alias);
+            this.desc = NameSpace.doc(this.alias);
             var bi = this.getBI();
                  
             for(var i =0; i < GI.enum_info_get_n_values(bi); i++) {
similarity index 72%
rename from JSDOC/Introspect/Field.js
rename to Introspect/Field.js
index 4eb915c..ee59e3a 100644 (file)
@@ -4,21 +4,22 @@ GI      = imports.gi.GIRepository;
 GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 
-imports['Object.js'].load(Object);
 
-console = imports['console.js'].console;
 
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
+Basic        = imports.Basic.Basic;
 
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
-
 
 /**
  * Field
  */
 
-Field = Object.define(
+Field = XObject.define(
     function(prop, memberOf, saveto, keylist) {
           
        this.name  =  GI.base_info_get_name(prop) ,
similarity index 70%
rename from JSDOC/Introspect/Interface.js
rename to Introspect/Interface.js
index 1de6ca1..a83a5ac 100644 (file)
@@ -1,23 +1,20 @@
 //<script type="text/javascript">
 //Gtk = imports.gi.Gtk;
  
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
-imports['Object.js'].load(Object);
-
-console = imports['console.js'].console;
+Base        = imports.Base.Base;
 
  
 
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Base = imports['JSDOC/Introspect/Base.js'].Base;
-
-
 
 /**
  * Interface
  */
 
-Interface = Object.define(
+Interface = XObject.define(
     function(ns, name) {
         Base.call(this, ns, name);
        
@@ -45,8 +42,8 @@ Interface = Object.define(
             this.genericBuildList('interface', 'method', methods, 'methods');
             
             
-            Introspect.ifaceList[this.alias] = Introspect.ifaceList[this.alias] || [];
-            this.implementedBy = Introspect.ifaceList[this.alias];
+            NameSpace.ifaceList[this.alias] = NameSpace.ifaceList[this.alias] || [];
+            this.implementedBy = NameSpace.ifaceList[this.alias];
             
               
            
diff --git a/Introspect/Link.js b/Introspect/Link.js
new file mode 100644 (file)
index 0000000..fb7d5a1
--- /dev/null
@@ -0,0 +1,386 @@
+//<script type="text/javascript">
+
+console = imports.console.console;
+
+XObject = imports.XObject.XObject
+
+
+/** Handle the creation of HTML links to documented symbols.
+       @constructor
+    * 
+    *  
+    * 
+*/
+
+Link = XObject.define(
+    function() {
+        this.alias = "";
+        this.src = "";
+        this.file = "";
+        this.text = "";
+        this.innerName = "";
+        this.classLink = false;
+        this.targetName = "";
+        
+        // statics..
+        Link.symbolsDir = Link.symbolsDir || '';
+        Link.base = Link.base || '';
+        Link.ext= Link.ext || '';
+        Link.srcDir= Link.srcDir || '';
+            
+        
+    },
+    Object,  {
+        
+        alias : "",
+        src : "",
+        file : "",
+        text : "",
+        innerName : "",
+        classLink : false,
+        targetName : "",
+        
+        
+        
+        toString : function() {
+            var linkString;
+            var thisLink = this;
+            
+            if (this.none) {
+                return 'none';
+            }
+            if (this.alias) {
+                
+                if (typeof(this.builtins[this.alias]) != 'undefined') {
+                    this.text = this.alias;
+                    return thisLink._makeExternLink(this.builtins[this.alias]);
+                }
+                
+                
+                return thisLink._makeSymbolLink(this.alias);
+                
+                /*
+                
+                linkString = this.alias.replace(/(^|[^a-z$0-9_#.:-])([|a-z$0-9_#.:-]+)($|[^a-z$0-9_#.:-])/i,
+                    function(match, prematch, symbolName, postmatch) {
+                        var symbolNames = symbolName.split("|");
+                        var links = [];
+                        for (var i = 0, l = symbolNames.length; i < l; i++) {
+                            thisLink.alias = symbolNames[i];
+                            links.push(thisLink._makeSymbolLink(symbolNames[i]));
+                        }
+                        return prematch+links.join("|")+postmatch;
+                    }
+                );
+                */
+            }
+            else if (this.extern) {
+                linkString = thisLink._makeExternLink(this.extern);
+            }
+            else if (this.src) {
+                linkString = thisLink._makeSrcLink(this.src);
+            }
+            else if (this.file) {
+                linkString = thisLink._makeFileLink(this.file);
+            }
+
+            return linkString;
+        },
+        
+        builtins : {
+            'Object' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Object',
+            //'Object...' : 'http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object',
+            'Array' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array',
+            'Function' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function',
+            'String' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/String',
+            'Number' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Number',
+            'Boolean' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Boolean',
+            'HTMLElement' : 'http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037'
+        },
+        
+        
+        toGnome: function(alias) 
+        {
+            this.file = "#";
+            var pr = alias.split('.');
+            var aa = alias;
+            var site = 'library.gnome.org';
+            var extra = '';
+            switch(pr[0]) {
+                case 'GIRepository':
+                   this.extern = 'http://live.gnome.org/GObjectIntrospection';
+                   aa = pr[0];
+                   break;
+                case 'Gio':   
+                case 'GLib':   
+                case 'GObject':   
+                    aa = pr.length > 1 ? 'G' + pr[1] : pr[0];
+                    break;
+                case 'GdkPixbuf':   
+                    aa = pr.length > 1 ? 'Gdk' + pr[1] : pr[0];
+                    break;
+                case 'GtkSource':   
+                    aa = pr.length > 1 ? pr[0] + pr[1] : 'GtkSourceView';
+                    break;
+                    
+                case 'Gst': 
+                    aa = pr.length > 1 ? pr[0] + pr[1] : 'GStreamer';
+                    break;
+                
+                case 'Pango':
+                    extra = ' GTK-Doc';
+                    break;
+                case 'GstController': 
+                case 'GstApp': 
+                case 'GstAudio': 
+                case 'GstBase': 
+                case 'GstCheck': 
+                case 'GstFft': 
+                case 'GstInterfaces': 
+                case 'GstNet': 
+                case 'GstNetbuffer': 
+                case 'GstPbutils': 
+                case 'GstRiff': 
+                case 'GstRtp': 
+                case 'GstRtsp': 
+                case 'GstSdp': 
+                case 'GstTag': 
+                case 'GstVideo': 
+                
+                    aa = pr.length > 1 ? 'Gst' + pr[1] : pr[0];
+                    break;
+                    
+                case 'Epiphany':     
+                    aa = pr.length > 1 ?  pr[1] : pr[0];
+                    break;
+                case 'WebKit':
+                    site = 'webkitgtk.org';
+                
+                default:
+                    
+                    aa = alias.replace('.', '');
+                    
+                    break;
+             
+            }
+            if (!this.extern) {
+                this.extern = 'http://www.google.com/search?hl=en&amp;' + 
+                        'q=site%3A' + site  + '+' + aa + extra +
+                        '&amp;btnI=I%27m+Feeling+Lucky&amp;meta=&amp;aq=f&amp;oq=';
+            }
+            
+            this.text =  aa;
+            return this;
+        },
+        
+        target : function(targetName) {
+            if (typeof(targetName) != 'undefined') this.targetName = targetName;
+            return this;
+        },
+        inner : function(inner) {
+            if (typeof(inner) != 'undefined') this.innerName = inner;
+            return this;
+        },
+        withText:  function(text) {
+            if (typeof(text) != 'undefined') this.text = text;
+            return this;
+        },
+        toSrc :function(filename) {
+            if (typeof(filename) != 'undefined') this.src = filename;
+            return this;
+        },
+        
+        toSymbolLong : function(alias)
+        {
+            this.show_full = true;
+            return this.toSymbol(alias)
+        },
+        toSymbol : function(alias) {
+            
+            
+            switch(alias) {
+                case 'boolean' : this.alias = 'Boolean'; return this;
+                case 'int' : this.alias = 'Number'; return this;
+                case 'uint' : this.alias = 'Number'; return this;
+                
+                case 'long' : this.alias = 'Number'; return this;
+                case 'ulong' : this.alias = 'Number'; return this;
+                
+                
+                case 'uint8' : this.alias = 'Number'; return this;
+                case 'int8' : this.alias = 'Number'; return this;
+                
+                case 'uint16' : this.alias = 'Number'; return this;
+                case 'uint16' : this.alias = 'Number'; return this;
+                
+                case 'int32' : this.alias = 'Number'; return this;
+                case 'uint32' : this.alias = 'Number'; return this;
+                
+                case 'uint64' : this.alias = 'Number'; return this;
+                case 'int64' : this.alias = 'Number'; return this;
+                
+                
+                case 'GType' : this.alias = 'Number'; return this;
+                case 'size' : this.alias = 'Number'; return this;
+                case 'ssize' : this.alias = 'Number'; return this;
+                
+                case 'float' : this.alias = 'Number'; return this;
+                case 'double' : this.alias = 'Number'; return this;
+                case 'time_t' : this.alias = 'Number'; return this;
+                // fixme - should find out more details..
+                case 'array' : this.alias = 'Array'; return this;
+                case 'gslist' : this.alias = 'Array'; return this;
+                case 'glist' : this.alias = 'Array'; return this; // homefully.
+                case 'ghash' : this.alias = 'Object'; return this; // homefully.
+                
+                
+                case 'error' : this.alias = 'Object'; return this; // homefully.
+                case 'filename' : this.alias = 'String'; return this; // hopefully..
+                case 'utf8' : this.alias = 'String'; return this;
+                
+                case 'void' : this.none = true; return this;
+                
+                
+            }
+            
+            
+            if (typeof(alias) != 'undefined') {
+                this.alias = new String(alias);
+            }
+            return this;
+        },
+        toClass : function(alias) {
+            this.classLink = true;
+            return this.toSymbol(alias);
+        },
+        toFile : function(file) {
+            if (typeof(file) != 'undefined') this.file = file;
+            return this;
+        },
+        
+        
+      
+
+        /** prefixed for hashes */
+
+
+        /** Appended to the front of relative link paths. */
+
+
+        symbolNameToLinkName : function(symbol) {
+            var linker = "";
+            if (symbol.isStatic) linker = ".";
+            else if (symbol.isInner) linker = "-";
+            
+            return linker+symbol.name;
+        },
+
+        
+
+
+        /** Create a link to a snother symbol. */
+        _makeSymbolLink :  function(alias) 
+        {
+            var target = '';
+            var txt = this.show_full ? alias : alias.split('.').pop();
+             return "<a href=\"./"+alias+".html\""+target+">"+txt+"</a>";    
+            
+            /*
+            // look for '/' in alias..
+            if (/\//.test(alias)) {
+                var bits = alias.split('/');
+                var ret = "";
+                for(var i=0; i < bits.length; i++) {
+                    if (i > 0) {
+                        ret +="/";
+                    }
+                    ret += this._makeSymbolLink(bits[i]);
+                }
+                return ret;
+                
+            }
+            
+            
+            */
+            
+            var linkBase = Link.base + Link.symbolsDir;
+            //var linkTo = Link.symbolSet.getSymbol(alias);
+            linkTo = "FIXME";
+            var linkPath;
+            var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
+            
+            // is it an internal link?
+            if (alias.charAt(0) == "#") {
+                linkPath = alias;
+                fullLinkPath = alias;
+            
+            // if there is no symbol by that name just return the name unaltered
+            } else if (!linkTo) {
+                
+                if (typeof(this.builtins[alias]) != 'undefined') {
+                    return "<a href=\""+ this.builtins[alias]+"\""+target+">"+alias+"</a>";
+                 }
+                
+                return this.text || alias;
+            
+            
+            // it's a symbol in another file
+            } else {
+
+                if (!linkTo.isConstructor && !linkTo.isNamespace) { // it's a method or property
+                    linkPath = escape(linkTo.memberOf) || "_global_";
+                    linkPath += Link.ext + "#" + this.symbolNameToLinkName(linkTo);
+                }
+                else {
+                    linkPath = escape(linkTo.alias);
+                    linkPath += Link.ext + (this.classLink? "":"#" +  "constructor");
+                }
+                //linkPath = linkBase + linkPath;
+                fullLinkPath = linkBase + linkPath;
+            }
+            
+            var linkText = this.text || alias;
+            
+            var link = {linkPath: linkPath, linkText: linkText, fullLinkPath: fullLinkPath};
+            
+            //if (typeof PluginManager != "undefined") {
+            //    JSDOC.PluginManager.run("onSymbolLink", link);
+            //}
+            
+            return "<a href=\""+link.fullLinkPath+"\""+target+">"+link.linkText+"</a>";
+        },
+
+
+        /** Create a link to a source file. */
+         _makeSrcLink : function(srcFilePath) {
+            var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
+                
+            // transform filepath into a filename
+            var srcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, "."); // was _
+            var lsrcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, ".");
+            var outFilePath = Link.base + Link.srcDir + srcFile.replace(/.js$/, '') + Link.ext;
+            
+            if (!this.text) this.text = FilePath.fileName(srcFilePath);
+            return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>";
+        },
+
+        /** Create a link to a source file. */
+         _makeFileLink : function(filePath) {
+            var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
+                
+            var outFilePath =  Link.base + filePath;
+
+            if (!this.text) this.text = filePath;
+            return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>";
+        },
+        
+        /** Create a link to a source file. */
+         _makeExternLink : function(filePath) {
+            var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
+                
+            if (!this.text) this.text = filePath;
+            return "<a href=\""+filePath+"\""+target+">"+this.text+"</a>";
+        }
+        
+});
\ No newline at end of file
similarity index 79%
rename from JSDOC/Introspect/Method.js
rename to Introspect/Method.js
index b26a4fb..2c44879 100644 (file)
@@ -3,13 +3,13 @@
 GI      = imports.gi.GIRepository;
 
 
-imports['Object.js'].load(Object);
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
-console = imports['console.js'].console;
+Basic        = imports.Basic.Basic;
 
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
+  
 /**
  * Methods, functions or consturctors
  */
@@ -17,7 +17,7 @@ Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
 
 
 
-Method = Object.define(
+Method = XObject.define(
     function(m, memberOf, saveto, keylist) {
         this.propertyType  = 'Method';
         
@@ -37,7 +37,7 @@ Method = Object.define(
         var retval = [ { 
                 name : 0, 
                 type :  this.typeToName(GI.callable_info_get_return_type(m)),
-                desc : Introspect.doc(memberOf.alias + '.' + n_original + '.return-value')
+                desc : NameSpace.doc(memberOf.alias + '.' + n_original + '.return-value')
         } ];
         
         
@@ -47,7 +47,7 @@ Method = Object.define(
         
         if ((n == 'c_new') && !args.length && memberOf.constructors.length) {
             
-            memberOf.constructors[0].doc = Introspect.doc(memberOf.alias + '.' + n_original);
+            memberOf.constructors[0].doc = NameSpace.doc(memberOf.alias + '.' + n_original);
             
             return false; // skip.
         }
@@ -62,7 +62,7 @@ Method = Object.define(
          // this is a bit messy, as we probably loose the doc's on new..
        
         
-        Object.extend(this, {
+        XObject.extend(this, {
             name : n,
             params: args,
             returns :  retval,
@@ -70,13 +70,13 @@ Method = Object.define(
             isStatic : !(flags & GI.IFunctionInfoFlags.IS_METHOD),
             memberOf : memberOf.alias,
             exceptions : [],
-            desc : Introspect.doc(memberOf.alias + '.' + n_original)
+            desc : NameSpace.doc(memberOf.alias + '.' + n_original)
         });
         // add descriptions to the arguments..
         this.params.map(function(p) {
             
             
-            p.desc = Introspect.doc(memberOf.alias + '.' + n_original + '.' + p.name);
+            p.desc = NameSpace.doc(memberOf.alias + '.' + n_original + '.' + p.name);
             //Seed.print(memberOf.alias + '.' + n_original + '.' + p.name + ':' +  p.desc);
             
         });
@@ -96,8 +96,8 @@ Method = Object.define(
             
             
             
-            Introspect.references[ty] = Introspect.references[ty] || [];
-            Introspect.references[ty].push(this);
+            NameSpace.references[ty] = NameSpace.references[ty] || [];
+            NameSpace.references[ty].push(this);
             addedto.push(ty);
         }
         
@@ -126,8 +126,8 @@ Method = Object.define(
             
             
             
-            Introspect.references[ty] = Introspect.references[ty] || [];
-            Introspect.references[ty].push(this);
+            NameSpace.references[ty] = NameSpace.references[ty] || [];
+            NameSpace.references[ty].push(this);
             addedto.push(ty);
         }
         
similarity index 93%
rename from JSDOC/Introspect.js
rename to Introspect/NameSpace.js
index f85d174..a169d1b 100644 (file)
@@ -5,24 +5,13 @@ GLib    = imports.gi.GLib;
 xml     = imports.libxml;
 
 
-imports['Object.js'].load(Object);
+XObject = imports.XObject.XObject;
 
-console = imports['console.js'].console;
-
-
-xnew    = imports['xnew.js'].xnew;
+console = imports.console.console;
 
  
 
-
-Introspect = {};
-
-xnew.load(Introspect,'JSDOC/Introspect');
-
-
-
-Object.extend(Introspect, {
-    
+NameSpace = {
    
     references : { }, 
     
@@ -42,10 +31,10 @@ Object.extend(Introspect, {
             
             while (true) {
                 
-                var fn = GLib.dir_read_name(gdir);
+                var fn = gdir.read_name ? gdir.read_name () : GLib.dir_read_name(gdir);
            //      console.log('trying ' +  fn);
                 if (!fn) {
-                    GLib.dir_close(gdir);
+                    gdir.close ? gdir.close() : GLib.dir_close(gdir);
                     return;;
                 }
                 if (!fn.match(/.typelib$/)) {
@@ -111,7 +100,7 @@ Object.extend(Introspect, {
                     ret.interfaces.push(GI.base_info_get_name(info));
                     continue;
                 case  GI.IInfoType.FUNCTION:
-                    new Introspect.Method(info, ret, 'functions', []);    
+                    new imports.Method.Method(info, ret, 'functions', []);    
                     continue;
                 
                 case  GI.IInfoType.CALLBACK:
@@ -133,7 +122,7 @@ Object.extend(Introspect, {
                     ret.unions.push(GI.base_info_get_name(info));
                     continue;
                 case  GI.IInfoType.CONSTANT:
-                    new Introspect.Constant(info, ret, 'values', []);
+                    new imports.Constant.Constant(info, ret, 'values', []);
                     
                     continue;
                 
@@ -236,6 +225,10 @@ Object.extend(Introspect, {
             
             var n =  getAttribute(element, 'name') ;
             //console.log("WALK" + n);
+            if (element.name == 'signal') {
+                path += '.signal';
+            }
+            
             if (n) {
                 path += path.length ? '.' : '';
                 path += n;
@@ -244,7 +237,6 @@ Object.extend(Introspect, {
                 path += '.return-value';
             }
             
-            
             var d =   getAttribute(element,'doc');
             if (d) {
              //   Seed.print(path + ':' + d);
@@ -288,16 +280,14 @@ Object.extend(Introspect, {
     registry : { },
     factory : function(type, ns, name) {
         if (typeof (this.registry[ns +'.' + name]) == 'undefined') {
-            this.registry[ns +'.' + name] = new Introspect[type](ns,name);
+            this.registry[ns +'.' + name] = new imports[type][type](ns,name);
             this.registry[ns +'.' + name].load();
         }
         
         return this.registry[ns +'.' + name];
     }
         
-            
-    
-});
+};
 
 
 
similarity index 61%
rename from JSDOC/Introspect/Property.js
rename to Introspect/Property.js
index 6630106..832152f 100644 (file)
@@ -2,21 +2,22 @@
 //Gtk = imports.gi.Gtk;
 GI      = imports.gi.GIRepository;
 
-imports['Object.js'].load(Object);
 
-console = imports['console.js'].console;
 
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
+Basic        = imports.Basic.Basic;
 
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
+   
 
 
 /**
  * Property
  */
 
-Property = Object.define(
+Property = XObject.define(
     function(prop, memberOf, saveto, keylist) {
         this.propertyType = 'Property';
         var n_original = GI.base_info_get_name(prop);
@@ -26,13 +27,13 @@ Property = Object.define(
         this.memberOf = memberOf.alias
         memberOf[saveto].push(this);
         keylist.push(this.name);
-        this.desc = Introspect.doc(this.memberOf + '.' + n_original);
+        this.desc = NameSpace.doc(this.memberOf + '.' + n_original);
         
 
         if (typeof(this.type) == 'string' && this.type.indexOf('.') > -1) {
         
-            Introspect.references[this.type] = Introspect.references[this.type] || [];
-            Introspect.references[this.type].push(this);
+            NameSpace.references[this.type] = NameSpace.references[this.type] || [];
+            NameSpace.references[this.type].push(this);
         }
         
     },
similarity index 75%
rename from JSDOC/Introspect/Signal.js
rename to Introspect/Signal.js
index 66b0994..9524512 100644 (file)
@@ -2,20 +2,16 @@
 //Gtk = imports.gi.Gtk;
 GI      = imports.gi.GIRepository;
 
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
+Basic        = imports.Basic.Basic;
 
-imports['Object.js'].load(Object);
+  
 
-console = imports['console.js'].console;
-
-
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Basic = imports['JSDOC/Introspect/Basic.js'].Basic;
-
-
-
-Signal = Object.define(
+Signal = XObject.define(
     function(sig, memberOf, saveto, keylist) {
 
         this.propertyType  = 'Signal';
@@ -31,13 +27,13 @@ Signal = Object.define(
         });
         var n_original  = GI.base_info_get_name(sig);
         
-        Object.extend(this,{
+        XObject.extend(this,{
             name : n_original.replace(/-/g,'_'),
             params : params,
             memberOf : memberOf.alias,
             exceptions : [],
             returns :   [ { type :  this.typeToName(GI.callable_info_get_return_type(sig)) } ],
-            desc : Introspect.doc(memberOf.alias + '.' + n_original)
+            desc : NameSpace.doc(memberOf.alias + '.signal.' + n_original)
         });
         memberOf[saveto].push(this);
         keylist.push(this.name);
@@ -55,8 +51,8 @@ Signal = Object.define(
             
             
             
-            Introspect.references[ty] = Introspect.references[ty] || [];
-            Introspect.references[ty].push(this);
+            NameSpace.references[ty] = NameSpace.references[ty] || [];
+            NameSpace.references[ty].push(this);
             addedto.push(ty);
         }
         
similarity index 85%
rename from JSDOC/Introspect/Struct.js
rename to Introspect/Struct.js
index a705d0e..a3a72dc 100644 (file)
@@ -2,21 +2,21 @@
 
 GI      = imports.gi.GIRepository;
 
-imports['Object.js'].load(Object);
 
 
-console = imports['console.js'].console;
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
+NameSpace   = imports.NameSpace.NameSpace;
 
+Base        = imports.Base.Base;
 
-
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Base = imports['JSDOC/Introspect/Base.js'].Base;
 /**
  * Struct
  */
 
-Struct = Object.define(
+Struct = XObject.define(
     function(ns, name) {
         Base.call(this, ns, name);
        
similarity index 84%
rename from JSDOC/Introspect/Union.js
rename to Introspect/Union.js
index b965512..723a756 100644 (file)
@@ -2,21 +2,21 @@
 
 GI      = imports.gi.GIRepository;
 
-imports['Object.js'].load(Object);
 
 
-console = imports['console.js'].console;
+XObject     = imports.XObject.XObject;
+console     = imports.console.console;
  
+Base        = imports.Base.Base;
 
-
-Introspect = imports['JSDOC/Introspect.js'].Introspect;
-Base = imports['JSDOC/Introspect/Base.js'].Base;
+  
+   
 
 /**
  * Union
  */
  
-Union = Object.define(
+Union = XObject.define(
     function(ns, name) {
         Base.call(this, ns, name);
        
diff --git a/JSDOC.js b/JSDOC.js
deleted file mode 100644 (file)
index bba697b..0000000
--- a/JSDOC.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// <script type="text/javascript">
-
-xnew =  imports['xnew.js'].xnew; 
-
-var JSDOC = {};
-
-xnew.load(JSDOC, 'JSDOC');
diff --git a/JSDOC/BuildDocs.js b/JSDOC/BuildDocs.js
new file mode 100644 (file)
index 0000000..3304ca9
--- /dev/null
@@ -0,0 +1,490 @@
+//<script type="text/javascript">
+/**
+       This is the main container for the JSDOC application.
+       @namespace
+*/
+Gio = imports.gi.Gio;
+
+XObject = imports.XObject.XObject;
+File = imports.File.File;
+
+Template = imports.JsTemplate.Template.Template;
+Link = imports.JsTemplate.Link.Link; // ?? fixme!??
+
+Parser      = imports.Parser.Parser;
+TextStream  = imports.TextStream.TextStream;
+TokenReader = imports.TokenReader.TokenReader;
+TokenStream = imports.TokenStream.TokenStream;
+Symbol      = imports.Symbol.Symbol;
+DocComment  = imports.DocComment.DocComment;
+
+// should not realy be here -- or anywhere...??
+
+function makeSortby(attribute) {
+    return function(a, b) {
+        if (a[attribute] != undefined && b[attribute] != undefined) {
+            a = a[attribute]; //.toLowerCase();
+            b = b[attribute];//.toLowerCase();
+            if (a < b) return -1;
+            if (a > b) return 1;
+            return 0;
+        }
+    }
+}
+
+Options = false; // refer to this everywhere!
+
+
+BuildDocs = {
+    
+    VERSION : "2.0.0",
+    
+    
+    srcFiles : [],
+    
+    
+    build : function (opts)
+    {
+        Options = opts; 
+        Options.init();
+        
+        Options.LOG.inform("JsDoc Toolkit main() running at "+new Date()+".");
+        //Options.LOG.inform("With options: ");
+        
+        if (Options.cacheDirectory.length && !File.isDirectory(Options.cacheDirectory)) {   
+            File.mkdir(Options.cacheDirectory)
+        }
+        
+        Options.srcFiles = this._getSrcFiles();
+        this._parseSrcFiles();
+        this.symbolSet = Parser.symbols;
+        
+        // this currently uses the concept of publish.js...
+        
+        this.publish();
+         
+        
+        
+    },
+    /**
+     * create a list of files in this.srcFiles using list of directories / files in Options.src
+     * 
+     */
+    
+    _getSrcFiles : function() 
+    {
+        this.srcFiles = [];
+        var _this = this;
+        var ext = ["js"];
+        if (Options.ext) {
+            ext = Options.ext.split(",").map(function($) {return $.toLowerCase()});
+        }
+        
+        for (var i = 0; i < Options.src.length; i++) {
+            // add to sourcefiles..
+            if (!File.isDirectory(Options.src[i])) {
+                _this.srcFiles.push(Options.src[i]);
+                continue;
+            }
+            File.list(Options.src[i] ).forEach(function($) {
+                if (Options['exclude-src'].indexOf($) > -1) {
+                    return;
+                }
+                var thisExt = $.split(".").pop().toLowerCase();
+                if (ext.indexOf(thisExt) < 0) {
+                    return;
+                }
+                _this.srcFiles.push(Options.src[i] + '/' + $);
+            });
+                
+        }
+        //Seed.print(JSON.stringify(this.srcFiles, null,4));Seed.quit();
+        return this.srcFiles;
+    },
+    /**
+     * Parse the source files.
+     * 
+     */
+
+    _parseSrcFiles : function() 
+    {
+        Parser.init();
+        
+        for (var i = 0, l = this.srcFiles.length; i < l; i++) {
+            
+            var srcFile = this.srcFiles[i];
+            
+            
+            var cacheFile = !Options.cacheDirectory.length ? false : 
+                Options.cacheDirectory + srcFile.replace(/\//g, '_') + ".cache";
+            
+            //print(cacheFile);
+            // disabled at present!@!!
+            
+            if (cacheFile  && File.exists(cacheFile)) {
+                // check filetime?
+                
+                var c_mt = File.mtime(cacheFile);
+                var o_mt = File.mtime(srcFile);
+                //println(c_mt.toSource());
+               // println(o_mt.toSource());
+               
+                // this check does not appear to work according to the doc's - need to check it out.
+               
+                if (c_mt > o_mt) { // cached time  > original time!
+                    // use the cached mtimes..
+                    print("Read " + cacheFile);
+                    var syms =  JSON.parse(File.read(cacheFile), function(k, v) {
+                        //print(k);
+                        if (typeof(v) != 'object') {
+                            return v;
+                        }
+                        if (typeof(v['*object']) == 'undefined') {
+                            return v;
+                        }
+                        var cls = imports[v['*object']][v['*object']];
+                        //print(v['*object']);
+                        delete v['*object'];
+                        var ret = new cls();
+                        XObject.extend(ret, v);
+                        return ret;
+                        
+                        
+                    });
+                    //print("Add sybmols " + cacheFile); 
+                    for (var sy in syms._index) {
+                      //  print("ADD:" + sy );
+                       Parser.symbols.addSymbol(syms._index[sy]);
+                    }
+                    continue;
+                }
+            }
+            
+            var src = ''
+            try {
+                Options.LOG.inform("reading : " + srcFile);
+                src = File.read(srcFile);
+            }
+            catch(e) {
+                Options.LOG.warn("Can't read source file '"+srcFile+"': "+e.message);
+                continue;
+            }
+
+            var txs = new TextStream(src);
+            
+            var tr = new TokenReader({ keepComments : true, keepWhite : true , sepIdents: false });
+            
+            var ts = new TokenStream(tr.tokenize(txs));
+        
+            Parser.parse(ts, srcFile);
+            
+            if (cacheFile) {
+                File.write(cacheFile,
+                  JSON.stringify(
+                    Parser.symbolsToObject(srcFile),
+                    null,2
+                  )
+                );
+            
+            }
+            //var outstr = JSON.stringify(
+            //    Parser.filesSymbols[srcFile]._index
+            //);
+            //File.write(cacheFile, outstr);
+             
+                
+    //         }
+        }
+        
+        
+        
+        Parser.finish();
+    },
+    
+     
+        
+    publish  : function() {
+        Options.LOG.inform("Publishing");
+         
+        // link!!!
+        
+        
+        Options.LOG.inform("Making directories");
+        if (!File.isDirectory(Options.target))
+            File.mkdir(Options.target);
+        if (!File.isDirectory(Options.target+"/symbols"))
+            File.mkdir(Options.target+"/symbols");
+        if (!File.isDirectory(Options.target+"/symbols/src"))
+            File.mkdir(Options.target+"/symbols/src");
+        
+        if (!File.isDirectory(Options.target +"/json")) {
+            File.mkdir(Options.target +"/json");
+        }
+        
+        Options.LOG.inform("Copying files from static: " +Options.templateDir);
+        // copy everything in 'static' into 
+        File.list(Options.templateDir + '/static').forEach(function (f) {
+            Options.LOG.inform("Copy " + Options.templateDir + '/static/' + f + ' to  ' + Options.target + '/' + f);
+            File.copyFile(Options.templateDir + '/static/' + f, Options.target + '/' + f,  Gio.FileCopyFlags.OVERWRITE);
+        });
+        
+        
+        Options.LOG.inform("Setting up templates");
+        // used to check the details of things being linked to
+        Link.symbolSet = this.symbolSet;
+        Link.base = "../";
+        
+        Link.srcFileFlatName = this.srcFileFlatName;
+        Link.srcFileRelName = this.srcFileRelName;
+        
+        var classTemplate = new Template({
+             templateFile : Options.templateDir  + "/class.html",
+             Link : Link
+        });
+        var classesTemplate = new Template({
+            templateFile : Options.templateDir +"/allclasses.html",
+            Link : Link
+        });
+        var classesindexTemplate = new Template({
+            templateFile : Options.templateDir +"/index.html",
+            Link : Link
+        });
+        var fileindexTemplate = new Template({   
+            templateFile : Options.templateDir +"/allfiles.html",
+            Link: Link
+        });
+
+        
+        classTemplate.symbolSet = this.symbolSet;
+        
+        
+        function hasNoParent($) {
+            return ($.memberOf == "")
+        }
+        function isaFile($) {
+            return ($.is("FILE"))
+        }
+        function isaClass($) { 
+            return ($.is("CONSTRUCTOR") || $.isNamespace); 
+        }
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        var symbols = this.symbolSet.toArray();
+        
+        var files = Options.srcFiles;
+        
+        for (var i = 0, l = files.length; i < l; i++) {
+            var file = files[i];
+            var targetDir = Options.target + "/symbols/src/";
+            this.makeSrcFile(file, targetDir);
+        }
+        
+        var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
+         
+         //Options.LOG.inform("classTemplate Process : all classes");
+            
+       // var classesIndex = classesTemplate.process(classes); // kept in memory
+        
+        Options.LOG.inform("iterate classes");
+        
+        var jsonAll = {}; 
+        
+        for (var i = 0, l = classes.length; i < l; i++) {
+            var symbol = classes[i];
+            var output = "";
+            
+            Options.LOG.inform("classTemplate Process : " + symbol.alias);
+            
+            
+            
+            
+            File.write(Options.target+"/symbols/" +symbol.alias+'.' + Options.publishExt ,
+                    classTemplate.process(symbol));
+            
+            jsonAll[symbol.alias] = this.publishJSON(symbol);
+            
+            
+            
+        }
+        
+        File.write(Options.target+"/json/roodata.json",
+                JSON.stringify({
+                    success : true,
+                    data : jsonAll
+                }, null, 1)
+        );
+        
+        
+        // regenrate the index with different relative links
+        Link.base = "";
+        //var classesIndex = classesTemplate.process(classes);
+        
+        Options.LOG.inform("build index");
+        
+        File.write(Options.target +  "/index."+ Options.publishExt, 
+            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"));
+        Options.LOG.inform("write files index");
+        
+        File.write(Options.target + "/files."+Options.publishExt, 
+            fileindexTemplate.process(allFiles)
+        );
+        
+        
+        
+        
+    },
+    /**
+     * JSON files are lookup files for the documentation
+     * - can be used by IDE's or AJAX based doc tools
+     * 
+     * 
+     */
+    publishJSON : function(data)
+    {
+        // what we need to output to be usefull...
+        // a) props..
+        var cfgProperties = [];
+        if (!data.comment.getTag('singleton').length) {
+            cfgProperties = data.configToArray();
+            cfgProperties = cfgProperties.sort(makeSortby("alias"));
+            
+        }
+        var props = []; 
+        //println(cfgProperties.toSource());
+        var p ='';
+        for(var i =0; i < cfgProperties.length;i++) {
+            p = cfgProperties[i];
+            props.push( {
+                name : p.name,
+                type : p.type,
+                desc : p.desc,
+                memberOf : p.memberOf == data.alias ? '' : p.memberOf
+            });
+        }
+        
+         
+        var ownEvents = data.methods.filter( function(e){
+                return e.isEvent && !e.comment.getTag('hide').length;
+            }).sort(makeSortby("name"));
+             
+        
+        var events = [];
+        var m;
+        for(var i =0; i < ownEvents.length;i++) {
+            m = ownEvents[i];
+            events.push( {
+                name : m.name.substring(1),
+                sig : this.makeFuncSkel(m.params),
+                type : 'function',
+                desc : m.desc
+            });
+        }
+        //println(props.toSource());
+        // we need to output:
+        //classname => {
+        //    propname => 
+        //        type=>
+        //        desc=>
+        //    }
+
+        var ret = {
+            props : props,
+            events: events
+        };
+        return ret;
+        
+        
+        
+        // b) methods
+        // c) events
+        
+        
+    },
+    srcFileRelName : function(sourceFile)
+    {
+      return sourceFile.substring(Options.baseDir.length+1);
+    },
+    srcFileFlatName: function(sourceFile)
+    {
+        var name = this.srcFileRelName(sourceFile);
+        name = name.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
+        return name.replace(/\:/g, "_") + '.html'; //??;
+        
+    },
+    
+    makeSrcFile: function(sourceFile) 
+    {
+        // this stuff works...
+     
+        
+        var name = this.srcFileFlatName(sourceFile);
+        
+        Options.LOG.inform("Write Source file : " + Options.target+"/symbols/src/" + name);
+        var pretty = imports.PrettyPrint.toPretty(File.read(  sourceFile));
+        File.write(Options.target+"/symbols/src/" + name, 
+            '<html><head>' +
+            '<title>' + sourceFile + '</title>' +
+            '<link rel="stylesheet" type="text/css" href="../../../css/highlight-js.css"/>' + 
+            '</head><body class="highlightpage">' +
+            pretty +
+            '</body></html>');
+    },
+    /**
+     * used by JSON output to generate a function skeleton
+     */
+    makeFuncSkel :function(params) {
+        if (!params) 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}";
+    }
+       
+    
+};
+  
+
+
+
+
+
+
+
+
+
index e75d672..62b3a73 100644 (file)
@@ -1,11 +1,11 @@
 //<script type="text/javscript">
-imports['Object.js'].load(Object);
+XObject = imports.XObject.XObject;
 
-JSDOC       = imports['JSDOC.js'].JSDOC; 
-console     = imports['console.js'].console; 
+console     = imports.console.console; 
 
 // make sure parent is loaded..
-TokenStream = imports['JSDOC/TokenStream.js'].TokenStream;
+TokenStream = imports.TokenStream.TokenStream;
 /**
  * 
  * base class for parsing segments of token array..
@@ -24,14 +24,14 @@ TokenStream = imports['JSDOC/TokenStream.js'].TokenStream;
        [ ] - collapse into first element.
  * c) items = , seperation within the above..
  * 
- * 
+ * usage: x = new Collapse(token_array)
  * 
  * 
  * 
  * 
  */ 
  
-Collapse = Object.define(
+Collapse = XObject.define(
     function (ar)
     {
          
@@ -62,7 +62,7 @@ Collapse = Object.define(
                 }
                 tok.prefix = '';
                 if (pref.length) {
-                    Roo.each(pref, function(e) {
+                    pref.forEach( function(e) {
                         if (!e) {
                             return;
                         }
@@ -88,9 +88,11 @@ Collapse = Object.define(
                   //  Seed.print(TokenStream.toString(ret));
                     return ret;
                 }
-               // console.log(tok.data);
+                // console.log(tok.data);
                 switch(tok.type) {
-                   
+                    case "VOID": 
+                        return ret; //EOF
+                        
                         
                     case "KEYW": 
                     case "TOKN":
@@ -109,7 +111,7 @@ Collapse = Object.define(
                                 
                                 var start = st.cursor;
                                 st.next(1);
-                                var add = st.balance(tok.name);
+                                var add = st.balance(tok.data);
                                 if (!add) {
                                     console.dump(tok);
                                     console.dump(start + '...' + st.cursor);
@@ -119,13 +121,17 @@ Collapse = Object.define(
                                 if (add) {
                                     add.shift();
                                 }
-                                //Seed.print(TokenStream.toString(aa));
+                                //Seed.print("ADD");
+                                //Seed.print(JSON.stringify(add, null,4));
+                                
                                 
                                 
                                 var toks = add ? this.collapse(add) : [];
                                 tok.items = false;
                                 tok.props = false;
                                 
+                                
+                                
                                 if (tok.data != '{') {
                                     // paramters or array elements..
                                     tok.items = this.toItems(toks, [',']);
@@ -163,7 +169,7 @@ Collapse = Object.define(
                         Seed.print("OOPS");
                         continue;
                     default : 
-                        Seed.print("OOPS");
+                        Seed.print("OOPS" + tok.type);
                         continue;
                 }
             }
@@ -233,8 +239,9 @@ Collapse = Object.define(
                    
                 }
             }
-             // last..
-            if (k.length) {
+             // last.. - if g.val.length is 0 then it's a trailing ','...
+             // we should really throw a syntax error in that case..
+            if (k.length && g.val.length) {
                 ret[k] = g;
             }
             return ret;
index 6b08e16..e6a0855 100644 (file)
@@ -8,9 +8,9 @@
    @arg packer {Packer} 
  */
  
-CompressWhite =  function (ts, packer)
+CompressWhite =  function (ts, packer, keepWhite)
 {
-    
+    keepWhite = keepWhite || false;
     ts.rewind();
     //var str = File.read(fn);
     var rep_var = 1;
@@ -21,6 +21,7 @@ CompressWhite =  function (ts, packer)
             break;
         }
         if (tok.type == "WHIT") {
+           
             continue;
             //if (tok._isDoc) {
             //    continue;
@@ -71,13 +72,37 @@ CompressWhite =  function (ts, packer)
                 //println("got = function() ");
                 var cu = ts.cursor;
                 
-                ts.balance("(");
-                ts.balance("{");
+                 if (!ts.balance("(") ){
+                    ts.dump(cu-40, cu);
+                    print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
+                    ts.dump(cu, cu+40);
+                    
+                    throw "could not find end lbrace!!!";
+                }
+                //print("AFTER BALANCE (");
+                //ts.dump(cu, ts.cursor);
+                //ts.cursor--; // cursor at the (
+                if (!ts.balance("{") ){
+                    ts.dump(cu-40, cu);
+                    print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
+                    ts.dump(cu, cu+40);
+                    
+                    throw "could not find end lbrace!!!";
+                }
+                //print('FN: '+ts.tokens[cu].toString());
+                //print('F1: '+ts.lookTok(1).toString());
+                //print('F2: '+ts.look(1,true).toString());
+                
                 // if next is not ';' -> make it so...
                 // although this var a=function(){},v,c; causes 
-                if (ts.lookTok(1).data != ';' && ts.lookTok(1).data != '}' && ts.lookTok(1,true).name == "NEWLINE") {
+                if (ts.lookTok(1).data != ';' && ts.lookTok(1).data != '}' && ts.look(1,true).name == "NEWLINE") {
+                    
                     ts.look(0).outData = ts.look(0).data+";";
+                   // print("ADDING SEMI: " + ts.look(0).toString());
+                    //ts.dump(cu, ts.cursor+2);
                 }
+                
+                 //ts.dump(cu, ts.cursor+2);
                 // restore.. 
                 ts.cursor = cu;
                 continue;
@@ -132,10 +157,14 @@ CompressWhite =  function (ts, packer)
                 var cu = ts.cursor;
                 
                 if (!ts.balance("{") ){
+                    ts.dump(cu-40, cu);
+                    print(">>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>");
+                    ts.dump(cu, cu+40);
+                    
                     throw "could not find end lbrace!!!";
                 }
                 // if next is not ';' -> make it so...
-
+                
                 if (ts.lookTok(1).data != ';' && ts.lookTok(1).data != '}' && ts.look(1,true).name=="NEWLINE") {
                     ts.look(0).outData = ts.look(0).data +";";
                 }
@@ -145,6 +174,8 @@ CompressWhite =  function (ts, packer)
             }
             
             // any more??
+            // a = function(....) { } 
+          
         }
         
         
@@ -240,13 +271,17 @@ CompressWhite =  function (ts, packer)
     var outoff = 0;
     out.length = ts.slen; // prealloc.
     out = '';
+    var tok;
     while (true) {
-        var tok = ts.nextTok();
-           
+        
+        tok = keepWhite ? ts.next() : ts.nextTok();
+        
         if (!tok) {
             break;
         }
-        
+        if (tok.type == "COMM") {
+            tok.outData = '\n';
+        }
         
         if (tok.type == "NAME"  && tok.identifier && tok.identifier.mungedValue && tok.identifier.mungedValue.length) {
             //f.write(tok.identifier.mungedValue);
diff --git a/JSDOC/DocComment.js b/JSDOC/DocComment.js
new file mode 100644 (file)
index 0000000..452ce3c
--- /dev/null
@@ -0,0 +1,232 @@
+//<Script type="text/javascript">
+
+XObject = imports.XObject.XObject;
+
+DocTag = imports.DocTag.DocTag;
+
+/**
+ * Create a new DocComment. This takes a raw documentation comment,
+ * and wraps it in useful accessors.
+ * @class Represents a documentation comment object.
+ * 
+ */ 
+
+DocComment = XObject.define(
+
+    function(/**String*/comment) {
+        this.isUserComment = true;
+        this.src           = "";
+        this.meta          = "";
+        this.tagTexts      = [];
+        this.tags          = []; // array of doctags..
+        if (typeof comment != "undefined") {
+            this.parse(comment);
+        }
+    }, 
+    Object, // extends
+    {
+        isUserComment : true,
+        src           : "",
+        meta          : "",
+        tagTexts      : [],
+        tags          : [],     
+    
+        /**
+         * serialize..
+         */
+        toJSON :function(t)
+        {
+            
+            var ret = { '*object' : 'DocComment' };
+            
+            var _this = this;
+            ['isUserComment','src', 'meta',  'tags'].forEach(function(k) {
+                ret[k] = _this[k];
+            })
+            
+            return ret;
+        },    
+        /**
+        * @requires JSDOC.DocTag
+        */
+        parse : function(/**String*/comment) {
+            if (comment == "") {
+                comment = "/** @desc */";
+                this.isUserComment = false;
+                
+            }
+            
+            this.src = DocComment.unwrapComment(comment);
+            
+            //println(this.src);
+            
+            
+            this.meta = "";
+            if (this.src.indexOf("#") == 0) {
+                this.src.match(/#(.+[+-])([\s\S]*)$/);
+                if (RegExp.$1) this.meta = RegExp.$1;
+                if (RegExp.$2) this.src = RegExp.$2;
+            }
+            this.hasTags = true;
+            if (!/^\s*@\s*\S+/m.test(this.src)) {
+                this.isUserComment = false;
+                this.hasTags = false;
+                
+                //return;
+            }
+            this.fixDesc();
+            
+            //if (typeof JSDOC.PluginManager != "undefined") {
+            //    JSDOC.PluginManager.run("onDocCommentSrc", this);
+            //}
+            
+            this.src = DocComment.shared+"\n"+this.src;
+            this.tags = [];
+            this.tagTexts = [];
+            
+            
+           
+            this.tagTexts = 
+                this.src
+                .split(/(^|[\r\n])\s*@/)
+                .filter(function($){return $.match(/\S/)});
+            
+            //println(this.tagTexts.toSource());
+            // fix tagText
+            
+            
+            
+            /**
+                The tags found in the comment.
+                @type JSDOC.DocTag[]
+             */
+             
+            this.tags = this.tagTexts.map(function($){return new DocTag($)});
+            
+            //println(this.tags.toSource());
+            this.tagTexts = []; // we dont need to store this..
+            
+            
+            //if (typeof JSDOC.PluginManager != "undefined") {
+            //     JSDOC.PluginManager.run("onDocCommentTags", this);
+            //}
+        },
+         
+
+        /**
+            If no @desc tag is provided, this function will add it.
+         */
+        fixDesc : function() {
+            if (this.meta && this.meta != "@+") return;
+            
+            
+            
+            // does not have any @ lines..
+            // -- skip comments without @!!
+            if (!/^\s*@\s*\S+/.test(this.src)) {
+                this.src = "@desc "+this.src;
+                // TAGS that are not \n prefixed!! ...
+                this.src = this.src.replace(/@\s*type/g, '\n@type'); 
+            
+                return;
+            }
+            // kdludge for stuff...
+            //this.src = this.src.replace(/@\s*type/g, '\n@type'); 
+            
+            // only apply @desc fix to classes..
+            if (!/\s*@(class|event|property)/m.test(this.src) ) {
+                return;
+            }
+            // if no desc - add it on the first line that is not a @
+            var lines = this.src.split("\n");
+            var nsrc = '';
+            var gotf = false;
+            
+            for(var i =0; i < lines.length;i++) {
+                var line = lines[i];
+                if (gotf) {
+                    nsrc += line + "\n";
+                    continue;
+                }
+                if (/^\s*[@\s]/.test(line)) { // line with @
+                    nsrc += line + "\n";
+                    continue;
+                }
+                gotf = true;
+                nsrc += '@desc ' + line + "\n";
+                
+            }
+             
+            this.src = nsrc;
+            
+            
+            
+        },
+      
+    /**
+        Provides a printable version of the comment.
+        @type String
+     */
+        toString : function() {
+            return this.src;
+        },
+
+    /*~t
+        assert("testing JSDOC.DocComment#fixDesc");
+        var com = new JSDOC.DocComment();
+        com.src = "foo";
+        assertEqual(""+com, "foo", "stringifying a comment returns the unwrapped src.");
+    */
+
+    /**
+        Given the title of a tag, returns all tags that have that title.
+        @type JSDOC.DocTag[]
+     */
+     /*
+     
+        toQDump : function(t)
+        {
+            //println(t.toSource());
+            var r =  JSDOC.toQDump(t, 'JSDOC.DocComment.fromDump({', '})', {}); // send it an empty object..
+            //println(r);
+            return r;
+        } ,
+        */
+     
+        getTag : function(/**String*/tagTitle) {
+            return this.tags.filter(function($){return (typeof($['title']) != 'undefined') && ($.title == tagTitle)});
+        }
+        
+});
+
+
+/// static methods..
+
+XObject.extend(DocComment, 
+    {
+        
+        /**
+         * Used to store the currently shared tag text.
+         */
+        shared : "",
+        
+        /**
+         * Remove slash-star comment wrapper from a raw comment string.
+         *  @type String
+         */
+        unwrapComment : function(/**String*/comment) {
+            if (!comment) return "";
+            var unwrapped = comment.replace(/(^\/\*\*|\*\/$)/g, "").replace(/^\s*\* ?/gm, "");
+            return unwrapped;
+        },
+
+        fromDump : function(t)
+        {
+            var ns = new DocComment();
+            for (var i in t) {
+                ns[i] = t[i];
+            }
+            return ns;
+        }
+});
\ No newline at end of file
diff --git a/JSDOC/DocTag.js b/JSDOC/DocTag.js
new file mode 100644 (file)
index 0000000..692d1f4
--- /dev/null
@@ -0,0 +1,228 @@
+//<script  type="text/javascript">
+XObject = imports.XObject.XObject;
+
+Options = imports.Options.Options;
+
+/**
+ * DocTag - represents a single A=b tag.
+ * @class DocTag
+ */
+DocTag = XObject.define(
+
+/**
+ * @constructor
+ * @arg {String} src
+ */
+
+    function(src) {
+        this.title        = "";
+        this.type         = "";
+        this.name         = "";
+        this.isOptional   = false;
+        this.defaultValue = "";
+        this.desc         = "";
+        if (typeof src != "undefined") {
+            this.parse(src);
+        }
+    }, 
+    Object,
+    {
+        
+        title: '',
+        type: '',
+        name : '',
+        isOptional : false,
+        defaultValue : '',
+        desc : '',
+        /**
+         * serialize..
+         */
+        toJSON :function(t)
+        {
+            var ret = { '*object' : 'DocTag' };
+            
+            for (var i in this) {
+                switch (typeof(this[i])) {
+                    case 'function':
+                       continue;
+                       continue;
+                        
+                    case 'string':
+                    case 'number':
+                    case 'boolean':                    
+                        ret[i] = this[i]; continue;
+                    default:
+                        print("unknown type:" + typeof(this[i]));
+                        Seed.quit();
+                   }
+            }
+            return ret;
+        },
+        
+
+
+        /**
+            Populate the properties of this from the given tag src.
+            @param {string} src
+         */
+        parse : function(src) {
+            if (typeof src != "string") throw "src must be a string not "+(typeof src);
+
+            try {
+                src = this.nibbleTitle(src);
+                //if (JSDOC.PluginManager) {
+                //    JSDOC.PluginManager.run("onDocTagSynonym", this);
+               // }
+                
+                src = this.nibbleType(src);
+                
+                // only some tags are allowed to have names.
+                if (this.title == "param" || this.title == "property" || this.title == "cfg") { // @config is deprecated
+                    src = this.nibbleName(src);
+                }
+            }
+            catch(e) {
+                if (Options.LOG) Options.LOG.warn(e);
+                else throw e;
+            }
+            this.desc = src; // whatever is left
+            
+            // example tags need to have whitespace preserved
+            if (this.title != "example") this.desc = this.desc.trim();
+            
+            //if (JSDOC.PluginManager) {
+            //    JSDOC.PluginManager.run("onDocTag", this);
+            //}
+        },
+
+        /**
+            Automatically called when this is stringified.
+         */
+        toString : function() {
+            return this.desc;
+        },
+         
+
+        /**
+            Find and shift off the title of a tag.
+            @param {string} src
+            @return src
+         */
+        nibbleTitle : function(src) {
+            if (typeof src != "string") throw "src must be a string not "+(typeof src);
+            
+            var parts = src.match(/^\s*(\S+)(?:\s([\s\S]*))?$/);
+
+            if (parts && parts[1]) this.title = parts[1];
+            if (parts && parts[2]) src = parts[2];
+            else src = "";
+            
+            return src;
+        },
+         
+        /**
+            Find and shift off the type of a tag.
+            @requires frame/String.js
+            @param {string} src
+            @return src
+         */
+        nibbleType : function(src) 
+        {
+            if (typeof src != "string") throw "src must be a string not "+(typeof src);
+            
+            if (src.match(/^\s*\{/)) {
+                var typeRange = this.balance(src,"{", "}");
+                if (typeRange[1] == -1) {
+                    throw "Malformed comment tag ignored. Tag type requires an opening { and a closing }: "+src;
+                }
+                this.type = src.substring(typeRange[0]+1, typeRange[1]).trim();
+                this.type = this.type.replace(/\s*,\s*/g, "|"); // multiples can be separated by , or |
+                src = src.substring(typeRange[1]+1);
+            }
+            
+            return src;
+        },
+         
+
+        /**
+            Find and shift off the name of a tag.
+            @requires frame/String.js
+            @param {string} src
+            @return src
+         */
+        nibbleName : function(src) {
+            if (typeof src != "string") throw "src must be a string not "+(typeof src);
+            
+            src = src.trim();
+            
+            // is optional?
+            if (src.charAt(0) == "[") {
+                var nameRange = this.balance(src,"[", "]");
+                if (nameRange[1] == -1) {
+                    throw "Malformed comment tag ignored. Tag optional name requires an opening [ and a closing ]: "+src;
+                }
+                this.name = src.substring(nameRange[0]+1, nameRange[1]).trim();
+                this.isOptional = true;
+                
+                src = src.substring(nameRange[1]+1);
+                
+                // has default value?
+                var nameAndValue = this.name.split("=");
+                if (nameAndValue.length) {
+                    this.name = nameAndValue.shift().trim();
+                    this.defaultValue = nameAndValue.join("=");
+                }
+            }
+            else {
+                var parts = src.match(/^(\S+)(?:\s([\s\S]*))?$/);
+                if (parts) {
+                    if (parts[1]) this.name = parts[1];
+                    if (parts[2]) src = parts[2].trim();
+                    else src = "";
+                }
+            }  
+
+            return src;
+        },
+        
+        balance : function(str, open, close) {
+            var i = 0;
+            while (str.charAt(i) != open) {
+                if (i == str.length) return [-1, -1];
+                i++;
+            }
+            
+            var j = i+1;
+            var balance = 1;
+            while (j < str.length) {
+                if (str.charAt(j) == open) balance++;
+                if (str.charAt(j) == close) balance--;
+                if (balance == 0) break;
+                j++;
+                if (j == str.length) return [-1, -1];
+            }
+            
+            return [i, j];
+}
+
+        
+        
+});
+
+// cached support?
+DocTag.fromDump = function(t)
+{
+    var ns = new DocTag();
+    for (var i in t) {
+        if (typeof(ns[i]) == "undefined") {
+            println("ERR:no default for DocTag:"+ i);
+        }
+       ns[i] = t[i];
+    }
+    return ns;
+}
index 7ba0099..975a148 100644 (file)
@@ -1,12 +1,13 @@
 //<script type="text/javscript">
-imports['Object.js'].load(Object);
 
-JSDOC   = imports['JSDOC.js'].JSDOC; 
+XObject = imports.XObject.XObject;
+
+
  
-console = imports['console.js'].console; 
+console = imports.console.console; 
 
 // make sure parent is loaded..
-RooFile = imports['JSDOC/RooFile.js'].RooFile;
+RooFile = imports.RooFile..RooFile;
 
 /**
  * 
@@ -21,7 +22,8 @@ RooFile = imports['JSDOC/RooFile.js'].RooFile;
 
 
 
-GtkFile  = Object.define(function (ar)
+GtkFile  = XObject.define(
+    function (ar)
     {
         GtkFile.superclass.constructor.call(this, ar);
        // console.log("STARTING OUTPUT");
index 51f9ad5..ef21c06 100644 (file)
@@ -55,6 +55,7 @@ Lang = {
         "=delete":     "DELETE",
         "=do":         "DO",
         "=else":       "ELSE",
+        "=eval":       "EVAL",
         "=false":      "FALSE",
         "=finally":    "FINALLY",
         "=for":        "FOR",
@@ -121,6 +122,8 @@ Lang = {
     },
 
     matching : function(name) {
+        name = typeof(this.puncNames[name]) == 'undefined' ? name : this.puncNames[name];
+        
         return this.matchingNames[name];
     },
     matchingNames : {
diff --git a/JSDOC/Options.js b/JSDOC/Options.js
new file mode 100644 (file)
index 0000000..7b81f38
--- /dev/null
@@ -0,0 +1,248 @@
+//<script type="text/javascript">
+/**
+ * Options management...
+ */
+XObject = imports.XObject.XObject;
+File = imports.File.File;
+
+Options = {
+
+    // generic stuff...
+    "--help"          : 'Show help',   // was h
+    "help": false,   // was h;se
+    
+    
+    // configurable settings.. - 
+    "usage" : "Usage seed jsdocbuild.js OPTIONS \n",
+    
+    
+    // options get defined like this..
+    "--src"           :  "source directory (either absolute - starts with "/" or relative " + 
+                        "- without, in which case it's added to baseDir",
+    "--exclude-src"       : 'Ex',   
+    "--baseDir"       :  'Base Directory (root directory of code)',
+    "--target"        :  'Target Directory (where html files go)',
+    "--cacheDirectory": 'Cached Files Directory (or blank to not cache)',
+    "--conf"          : 'Read From a Configuration file',       // was c. - configuration file.. - parsed with JSON.parse
+    "--templateDir"      : 'Template Directory',   // was t.
+    // "recurse": false,   // was r. - not supported..
+    "--ext"           :  'Extension of code files to read (normally js)',   // was x.
+    "--publishExt"    : 'Extension of html files to write (normally html)',
+    //"private": '',   // was p
+    //"allfunctions": '',   // was a
+    //"encoding": '',   // was e.
+    //"nocode": '',  // was n
+    //"out": '',   // was o.
+    //"suppress": '',  // was s ??? used?
+    "--outputSource" : 'Output the Source code to symbols/src/* (boolean)',
+    //"testmode": '',  // was t
+    
+    "--verbose"       : 'Show verbose messages',   // was v
+    //"disablecache": '',   // was C -- not needed? - see if cacheDirectory was set..
+    //"define" : [],   // was D.
+    //"handler" : [],  // was H -- not supported..
+
+    
+    // and now the defaults.. (which type can be infered from..)
+    "src" : [],
+    "exclude-src" : [],
+    "baseDir" :  '',  // base directory - 
+    "target" : '',   // was d. ?? source directory (needed to put temporary files..)
+    "cacheDirectory" : '',
+    "conf" : '',       // was c. - configuration file.. - parsed with JSON.parse
+    "templateDir": '',   // was t.
+    // "recurse": false,   // was r. - not supported..
+    "ext": 'js',   // was x.
+    "publishExt" : 'html',
+    "private": '',   // was p
+    "allfunctions": '',   // was a
+    "encoding": '',   // was e.
+    "nocode": '',  // was n
+    "out": '',   // was o.
+    "suppress": '',  // was s ??? used?
+    "outputSource" : true,
+    "testmode": '',  // was t
+    
+    "verbose": '',   // was v
+    "disablecache": '',   // was C
+    "define" : [],   // was D.
+    "handler" : [],  // was H -- not supported..
+    
+    
+    "version" : "1.0",
+    "copyright" : "LGPL",
+    
+    LOG : {
+        warn : function(str) {
+            print("Warn: " +str );
+        },
+        inform : function(str) {
+            print("Inform: " +str );
+        },
+        close : function() { },
+        flush : function() { },
+        out: false,
+        warnings : [],
+        verbose : false    
+    },
+    init : function()
+    {
+        
+        if (this.help) {
+            this.showHelp();
+          
+        }
+        
+        // the reset of this is specific to JSDOC - and can not be moved to a generic handler..
+        
+         
+        this.LOG.verbose = this.verbose;
+        
+        if (!this.baseDir) { // should we set this to cwd?
+            throw {
+                name: "ArgumentError", 
+                message: "No baseDir specified" 
+            };
+        }
+        
+        // this is most likely to come from the command line..
+        if (this.conf) {
+            var conf = this.conf[0] == '/' ? this.conf : this.baseDir + '/' + this.conf;
+        
+            XObject.extend(this, JSON.parse(File.read(conf)));;
+        }
+        // help ?? -- usage..
+       
+        if (!this.src.length) {
+            throw {
+                name: "ArgumentError", 
+                message: "No source directories specified" 
+            };
+        }
+        // append full path to source directories.
+        var _this= this;
+        var src = this.src;
+        this.src = [];
+        src.forEach(function(v, i) {
+            if (!v.length || v[0] != '/') {
+                v = _this.baseDir + (v.length ?  '/' + v : '');
+            }
+            if (!File.exists(v)) {
+                throw {
+                    name: "ArgumentError", 
+                    message: "invalid Source Directory : " +  v
+                };
+            }
+            _this.src.push(v);
+        });
+        
+        
+        if (!this.templateDir) {
+            throw {
+                name: "ArgumentError", 
+                message: "No templateDir Directory specified" 
+            };
+        }
+        if (this.templateDir[0] !='/') {
+            this.templateDir = this.baseDir + '/' + this.templateDir;
+        }
+        
+        
+        if (!this.target) {
+            throw {
+                name: "ArgumentError", 
+                message: "No directory specified" 
+            };
+        }
+        
+        //print(JSON.stringify(this, null,4));
+        
+        // should cacheDirectory be a subdirectory of target??
+        // if not set..
+        //if (!this.cacheDirectory) {
+        //    throw {
+        //        name: "ArgumentError", 
+        //        message: "No cacheDirectory specified" 
+        //    };
+        // }
+        
+    },
+    /** 
+     *  this might be nice as a standard bit of code..
+     */
+       
+    parseArgv : function() 
+    {
+        
+        var args = Array.prototype.slice.call(Seed.argv);
+        args.shift(); //seed
+        args.shift(); // pack.js
+        
+        for(var i =0; i < args.length;i++) {
+            if (args[i].substring(0,2) != '--') {
+                
+                throw {
+                    name: "ArgumentError", 
+                    message: "Unknown argument: " + args[i] 
+                };
+            }
+            var a = args[i].substring(2);
+            if (typeof(this[args[i]]) == 'undefined') {
+                throw {
+                    name: "ArgumentError", 
+                    message: "Unknown argument: " + args[i] 
+                };
+            }
+            // type!!?!?
+            if (typeof(this[a]) == 'string') {
+                this[a] = args[i+1];
+                i++;
+                continue;
+            }
+            if (typeof(this[a]) == 'boolean') {
+                if (['false', 'true'].indexOf(args[i+1]) < 0) {
+                    throw {
+                        name: "ArgumentError", 
+                        message: "Unknown value for : " + args[i] + ' : ' +  args[i+1] 
+                    };
+                }
+                this[a] = args[i+1] == 'true';
+                i++;
+                continue;
+            }
+            if (typeof(this[a]) == 'object') { // tecnically an array.
+                i++;
+                while(i < args.length)
+                {
+                    if (args[i].substring(0,2) == '--'){
+                        i--;
+                        break;
+                    }
+                    this[a].push(args[i]);
+                    i++;
+                }
+                
+                continue;
+            }
+            throw {
+                name: "ArgumentError", 
+                message: "Do not know how to handle: " + a + ' ' + typeof(this[a])
+            };  
+        }
+        
+        
+    },
+    
+    
+    showHelp: function()
+    {
+        print(this.usage);
+        for(var i in this) {
+            if (i.substring(0,2) != '--') {
+                continue;
+            }
+            print( i + '  ARG  : ' + this[i]);
+            throw "DONE";
+        }
+    }
+}
\ No newline at end of file
index d04e630..933156d 100644 (file)
@@ -2,11 +2,12 @@
 XObject         = imports.XObject.XObject;
 File            = imports.File.File;
 
-TextStream      = imports['JSDOC/TextStream.js'].TextStream;
-TokenReader     = imports['JSDOC/TokenReader.js'].TokenReader;
-ScopeParser     = imports['JSDOC/ScopeParser.js'].ScopeParser;
-TokenStream     = imports['JSDOC/TokenStream.js'].TokenStream;
-CompressWhite   = imports['JSDOC/CompressWhite.js'].CompressWhite;
+TextStream      = imports.TextStream.TextStream;
+TokenReader     = imports.TokenReader.TokenReader;
+ScopeParser     = imports.ScopeParser.ScopeParser;
+TokenStream     = imports.TokenStream.TokenStream;
+CompressWhite   = imports.CompressWhite.CompressWhite;
+Collapse        = imports.Collapse.Collapse;
 
 GLib = imports.gi.GLib;
 /**
@@ -70,9 +71,12 @@ Packer = function(cfg)
 {
     
     XObject.extend(this, cfg);
-    
-    if (this.srcfile) {
-        this.loadSourceFile();
+    var _this = this;
+    if (this.srcfiles && this.srcfiles.length) {
+        this.srcfiles.forEach(function(f) {
+            _this.loadSourceFile(f);
+        });
+        
     }
     
     if (!this.files) {
@@ -89,7 +93,7 @@ Packer.prototype = {
     /**
      * @prop srcfiles {String} file containing a list of files/or classes to use.
      */
-    srcfiles : false,
+    srcfile : false,
     
     /**
      * @prop files {Array} list of files to compress (must be full path)
@@ -125,9 +129,9 @@ Packer.prototype = {
     out : '', // if no target is specified - then this will contain the result
     
     
-    loadSourceFile : function()
+    loadSourceFile : function(srcfile)
     {
-        var lines = File.read(this.srcfile).split("\n");
+        var lines = File.read(srcfile).split("\n");
         var _this = this;
         lines.forEach(function(f) {
             
@@ -310,7 +314,13 @@ Packer.prototype = {
     pack : function (str,fn,minfile)
     {
     
-        var tr = new  TokenReader(  { keepDocs :true, keepWhite : true,  keepComments : true, sepIdents : true });
+        var tr = new  TokenReader(  { 
+            keepDocs :true, 
+            keepWhite : true,  
+            keepComments : true, 
+            sepIdents : true,
+            collapseWhite : false
+        });
         this.timerPrint("START" + fn);
         
         // we can load translation map here...
@@ -328,8 +338,12 @@ Packer.prototype = {
         // and replace if we are generating a different language..
         
         this.timerPrint("Tokenized");
+        //var ts = new TokenStream(toks);
+        //print(JSON.stringify(toks, null,4 )); Seed.quit();
+        var ts = new Collapse(toks);
+       // print(JSON.stringify(ts.tokens, null,4 )); Seed.quit();
         //return;//
-        var sp = new ScopeParser(new TokenStream(toks));
+        var sp = new ScopeParser(ts);
         this.timerPrint("Converted to Parser");
         sp.packer = this;
         sp.buildSymbolTree();
@@ -337,7 +351,10 @@ Packer.prototype = {
         sp.mungeSymboltree();
         this.timerPrint("Munged Sym tree");
         print(sp.warnings.join("\n"));
-        var out = CompressWhite(sp.ts, this);
+        
+        
+        //var out = CompressWhite(new TokenStream(toks), this, true); // do not kill whitespace..
+        var out = CompressWhite(new TokenStream(toks), this, false);
         this.timerPrint("Compressed");
         return out;
         
diff --git a/JSDOC/Parser.js b/JSDOC/Parser.js
new file mode 100644 (file)
index 0000000..e814263
--- /dev/null
@@ -0,0 +1,208 @@
+//<script type="text/javascript">
+
+Walker2      = imports.Walker2.Walker2;
+Symbol      = imports.Symbol.Symbol;
+SymbolSet      = imports.SymbolSet.SymbolSet;
+DocComment  = imports.DocComment.DocComment;
+Options     = imports.Options.Options;
+/**
+ * Parser is a static  instance..
+ * 
+ * 
+ */
+Parser = {
+       conf: { 
+        loaded: false 
+    },
+    
+    walker : false, // will be JSDOC.Walker()
+    symbols : false, //will be JSDOC.SymbolSet()
+    
+    filesSymbols : { },
+    
+    /** 
+    * global init once 
+    * 
+    */
+         
+    init: function() {
+        if (this.conf.loaded) {
+            return;
+        }
+        //print("init parser conf!?");
+        this.conf = {
+            loaded : true,
+            //ignoreCode:                 Options.n,
+            ignoreAnonymous:           true, // factory: true
+            treatUnderscoredAsPrivate: true, // factory: true
+            explain:                   false // factory: false
+        };
+         
+               this.symbols = new  SymbolSet();
+               //this.walker = new JSDOC.Walker();
+        //JSDOC.Parser.filesSymbols = {};
+       },
+
+
+
+    /**
+     * Parse a token stream.
+     * @param {JSDOC.TokenStream} token stream
+     * @param {String} filename 
+         
+     */
+    
+    
+    parse : function(ts, srcFile) 
+    {
+        this.init();
+        
+        
+        // not a nice way to set stuff...
+        
+        Symbol.srcFile = (srcFile || "");
+        DocComment.shared = ""; // shared comments don't cross file boundaries
+        
+       
+        
+        
+        
+        this.filesSymbols[Symbol.srcFile] = new SymbolSet();
+        
+        //Options.LOG.inform("Parser - run walker");
+        this.walker = new  Walker2(ts);
+        this.walker.buildSymbolTree();
+        
+        
+        
+        //this.walker.walk(ts); // adds to our symbols
+       // throw "done sym tree";
+        //Options.LOG.inform("Parser - checking symbols");
+        // filter symbols by option
+        for (p in this.symbols._index) {
+            var symbol = this.symbols.getSymbol(p);
+            
+           // print(JSON.stringify(symbol, null,4));
+            
+            if (!symbol) continue;
+            
+            if (symbol.isPrivate) {
+                this.symbols.deleteSymbol(symbol.alias);
+                continue;
+            }
+            
+            if (symbol.is("FILE") || symbol.is("GLOBAL")) {
+                continue;
+            }
+            //else if (!Options.a && !symbol.comment.isUserComment) {
+                //print("Deleting Symbols (no a / user comment): " + symbol.alias);
+                //this.symbols.deleteSymbol(symbol.alias);
+                //this.filesSymbols[Symbol.srcFile].deleteSymbol(symbol.alias);
+            //}
+            
+            if (/#$/.test(symbol.alias)) { // we don't document prototypes - this should not happen..
+                // rename the symbol ??
+                /*if (!this.symbols.getSymbol(symbol.alias.substring(0,symbol.alias.length-1))) {
+                    // rename it..
+                    print("Renaming Symbol (got  a #): " + symbol.alias);
+                    var n = '' + symbol.alias;
+                    this.symbols.renameSymbol( n ,n.substring(0,n-1));
+                    this.filesSymbols[Symbol.srcFile].renameSymbol( n ,n.substring(0,n-1));
+                    continue;
+                }
+                */
+                print("Deleting Symbols (got  a #): " + symbol.alias);
+                
+                this.symbols.deleteSymbol(symbol.alias);
+                this.filesSymbols[Symbol.srcFile].deleteSymbol(symbol.alias);
+            
+            }
+        }
+        //print(prettyDump(toQDump(this.filesSymbols[Symbol.srcFile]._index,'{','}')));
+        //print("AfterParse: " + this.symbols.keys().toSource().split(",").join(",\n   "));
+        return this.symbols.toArray();
+    },
+
+       
+       addSymbol: function(symbol) 
+    {
+         //print("PARSER addSYMBOL : " + symbol.alias);
+        
+               // if a symbol alias is documented more than once the last one with the user docs wins
+               if (this.symbols.hasSymbol(symbol.alias)) {
+                       var oldSymbol = this.symbols.getSymbol(symbol.alias);
+            
+                       if (oldSymbol.comment.isUserComment && !oldSymbol.comment.hasTags) {
+                               if (symbol.comment.isUserComment) { // old and new are both documented
+                                       Options.LOG.warn("The symbol '"+symbol.alias+"' is documented more than once.");
+                               }
+                               else { // old is documented but new isn't
+                                       return;
+                               }
+                       }
+               }
+               
+               // we don't document anonymous things
+               if (this.conf.ignoreAnonymous && symbol.name.match(/\$anonymous\b/)) return;
+
+               // uderscored things may be treated as if they were marked private, this cascades
+               if (this.conf.treatUnderscoredAsPrivate && symbol.name.match(/[.#-]_[^.#-]+$/)) {
+                       symbol.isPrivate = true;
+               }
+               
+               // -p flag is required to document private things
+               if ((symbol.isInner || symbol.isPrivate) && !Options.p) return;
+               
+               // ignored things are not documented, this doesn't cascade
+               if (symbol.isIgnored) return;
+        // add it to the file's list... (for dumping later..)
+        if (Symbol.srcFile) {
+            this.filesSymbols[Symbol.srcFile].addSymbol(symbol);
+        }
+               
+               this.symbols.addSymbol(symbol);
+       },
+       
+       addBuiltin: function(name) {
+  
+               var builtin = new Symbol(name, [], "CONSTRUCTOR", new DocComment(""));
+               builtin.isNamespace = false;
+               builtin.srcFile = "";
+               builtin.isPrivate = false;
+        this.addSymbol(builtin);
+               return builtin;
+       },
+       
+               
+       finish: function() {
+               this.symbols.relate();          
+               
+               // make a litle report about what was found
+               if (this.conf.explain) {
+                       var symbols = this.symbols.toArray();
+                       var srcFile = "";
+                       for (var i = 0, l = symbols.length; i < l; i++) {
+                               var symbol = symbols[i];
+                               if (srcFile != symbol.srcFile) {
+                                       srcFile = symbol.srcFile;
+                                       print("\n"+srcFile+"\n-------------------");
+                               }
+                               print(i+":\n  alias => "+symbol.alias + "\n  name => "+symbol.name+ "\n  isa => "+symbol.isa + "\n  memberOf => " + symbol.memberOf + "\n  isStatic => " + symbol.isStatic + ",  isInner => " + symbol.isInner);
+                       }
+                       print("-------------------\n");
+               }
+       },
+    /**
+     * return symbols so they can be serialized.
+     */
+    symbolsToObject : function(srcFile)
+    {
+        //this.filesSymbols[srcFile] is a symbolset..
+        return this.filesSymbols[srcFile];
+        
+            //    Parser.filesSymbols[srcFile]._index
+    }
+
+}
\ No newline at end of file
diff --git a/JSDOC/PrettyPrint.js b/JSDOC/PrettyPrint.js
new file mode 100644 (file)
index 0000000..3101f30
--- /dev/null
@@ -0,0 +1,83 @@
+
+// <script type="text/javascript">
+
+TokenReader = imports.TokenReader.TokenReader;
+ScopeParser= imports.ScopeParser.ScopeParser;
+Collapse = imports.Collapse.Collapse;
+TextStream = imports.TextStream.TextStream;
+
+function  escapeHTML(str) { 
+    return str.replace(/&/g,'&amp;').
+            replace(/>/g,'&gt;'). 
+            replace(/</g,'&lt;'). 
+            replace(/"/g,'&quot;');
+};
+
+function toPretty(str)
+{
+    
+    var txs = new TextStream(str);
+    var tr = new TokenReader({ keepComments : true, keepWhite : true });
+    var toks = tr.tokenize(txs)
+    
+    //var sp = new ScopeParser(new Collapse(toks));
+    //sp.buildSymbolTree();
+    
+    
+   // sp.mungeSymboltree();
+    var r = '';
+    //r += sp.warnings.join("<BR>");
+    //r == "<BR>";
+    
+    
+    
+    
+    var cs = ''; // current style..
+    
+    function toStyle(tok)
+    {
+        if (tok.is("WHIT") || tok.is("COMM") ) {
+            if (tok.data.indexOf("/") > -1) {
+                return 'comment';
+            }
+            return cs; // keep the same..
+        }
+        if (tok.is('STRN')) {
+            return 'string';
+        }
+        // other 'vary things??
+        if (tok.is('NAME') || tok.data == '.' || tok.name == 'THIS') {
+            return 'var';
+        }
+        if (/^[a-z]+/i.test(tok.data)) {
+            return 'keyword';
+        }
+        return 'syntax'
+    }
+    // loop through and print it...?
+    
+    
+    for (var i = 0;i < toks.length; i++) {
+        var ns = toStyle(toks[i]);
+        if (ns != cs) {
+            // change of style
+            if (cs.length) r +='</span>';
+            r +='<span class="jsdoc-'+ns+'">';
+            cs = ns;
+        }
+        if (toks[i].identifier) {
+            
+            r += '<span class="with-ident2">' +
+                escapeHTML(toks[i].data) + '</span>';
+                continue;
+                
+        }
+        r += escapeHTML(toks[i].data); //.replace(/\n/g, "<BR/>\n");
+    }
+    if (cs.length) r +='</span>';
+    
+    return '<code class="jsdoc-pretty">'+r+'</code>';
+    
+        
+}
index ce477c9..5cca0a5 100644 (file)
@@ -1,9 +1,8 @@
 //<script type="text/javscript">
 
-imports['Object.js'].load(Object);
-JSDOC       = imports['JSDOC.js'].JSDOC;
-console     = imports['console.js'].console;
-TokenStream = imports['JSDOC/TokenStream.js'].TokenStream;
+XObject = imports.XObject.XObject;
+console     = imports.console.console;
+TokenStream = imports.TokenStream.TokenStream;
 /**
  * 
  * this takes our collased file, and turns it into the config array..
@@ -15,7 +14,7 @@ TokenStream = imports['JSDOC/TokenStream.js'].TokenStream;
  * 
  */
 
-RooFile  =  Object.define(
+RooFile  =  XObject.define(
     function (ar)
     {
         RooFile.superclass.constructor.call(this, ar);
@@ -112,7 +111,7 @@ RooFile  =  Object.define(
                         
                         
                     };
-                    Object.extend(this.cfg, this.parseProps(this.tokens[pos+1].props));
+                    XObject.extend(this.cfg, this.parseProps(this.tokens[pos+1].props));
                     return;
                     
                 }
@@ -135,7 +134,7 @@ RooFile  =  Object.define(
                 
                 
                     
-                Object.extend(this.cfg, this.parseProps(this.tokens[pos+1].items[1][0].props));
+                XObject.extend(this.cfg, this.parseProps(this.tokens[pos+1].items[1][0].props));
                 return;
                 
             }
@@ -156,7 +155,7 @@ RooFile  =  Object.define(
                     '*extends' : this.tokens[pos+1].data
                 };
                     
-                Object.extend(this.cfg, this.parseProps(this.tokens[pos+2].items[0][0].props));
+                XObject.extend(this.cfg, this.parseProps(this.tokens[pos+2].items[0][0].props));
                 
                 return;
                 
@@ -170,7 +169,7 @@ RooFile  =  Object.define(
             if (pos > -1) {
                 
                 this.cfg['*extends'] = this.tokens[pos+1].items[1][0].data;
-                Object.extend(this.cfg, this.parseProps(this.tokens[pos+1].items[2][0].props));
+                XObject.extend(this.cfg, this.parseProps(this.tokens[pos+1].items[2][0].props));
                 
                 // no more..
                 return;
@@ -182,7 +181,7 @@ RooFile  =  Object.define(
             if (pos > -1) {
                 
                 this.cfg['*extends'] = this.tokens[pos+1].items[1][0].data;
-                Object.extend(this.cfg, this.parseProps(this.tokens[pos+1].items[2][0].props));
+                XObject.extend(this.cfg, this.parseProps(this.tokens[pos+1].items[2][0].props));
                 
                 // no more..
                 return;
@@ -321,7 +320,7 @@ RooFile  =  Object.define(
             if (!ret.items && fakeItems.length) {
                 ret.items = [];
             }
-            Object.extend(fakeItems, function(e) {
+            XObject.extend(fakeItems, function(e) {
                 ret.items.push(e);
             })
             // merge fakeItems;
index 84e86da..aa145c3 100644 (file)
@@ -6,11 +6,11 @@
 * // FIXME - I need this to do next() without doccomments..
 */
 
-Identifier = imports['JSDOC/Identifier.js'].Identifier
+Identifier = imports.Identifier.Identifier
 XObject = imports.XObject.XObject; 
 
 
-function Scope(braceN, parent, startTokN, lastIdent)
+function Scope(braceN, parent, startTokN, lastIdent, token)
 {
     if (lastIdent.length) {
        //  println("NEW SCOPE: " + lastIdent);
@@ -23,9 +23,10 @@ function Scope(braceN, parent, startTokN, lastIdent)
     this.subScopes = [];
     this.hints = { };
     this.ident = lastIdent;
+    this.gid = Scope.gid++;
     
-    
-    //println("ADD SCOPE(" + this.id + ") TO "+ (parent ? this.parent.id : 'TOP') + "<BR/>");
+    //print("ADD SCOPE(" + this.gid + ") TO "+ (parent ? this.parent.gid : 'TOP') + ' : ' + 
+    //    (token ? token.toString() : ''));
     
     if (parent) {
         this.parent.subScopes.push(this);
@@ -54,7 +55,7 @@ Scope.prototype = {
     protectedVars : {}, // only used by to parent..
     declareIdentifier : function(symbol, token) {
         
-        //println("ADD IDENT(" + this.id + "):<B>" + symbol+"</B><BR/>");
+        //print("SCOPE : " + this.gid +  " :SYM: " + symbol + " " + token.toString()+"");
         
         if (typeof(this.identifiers[symbol])== 'undefined') {
             
@@ -69,11 +70,22 @@ Scope.prototype = {
                 // then it's global... 
                 this.identifiers[symbol].toMunge  = false;
         }
+         
+        
         this.addToParentScope(symbol);
         return this.identifiers[symbol];
     },
-    getIdentifier : function(symbol) {
-        return (typeof(this.identifiers[symbol])== 'undefined') ? false : this.identifiers[symbol];
+    getIdentifier : function(symbol, token) {
+        if (typeof(this.identifiers[symbol])== 'undefined') {
+            if (['String', 'Date'].indexOf(symbol)> -1) {
+                return false;
+            }
+            
+            //print("SCOPE : " + this.gid +" = SYMBOL NOT FOUND?" + token.toString());
+            return false;
+        }
+         //print("SCOPE : " + this.gid +" = FOUND:" + token.toString());
+        return this.identifiers[symbol];
     },
     
     addHint : function(varName, varType) {
@@ -229,7 +241,7 @@ Scope.prototype = {
                 
                 if (!repsym.length) {
                     if (!freeSymbols.length) {
-                        addSyms(JSDOC.Scope.twos); 
+                        addSyms(Scope.twos); 
                     }
                     repsym = freeSymbols.shift(); // pop off beginngin???
                 }
@@ -313,4 +325,4 @@ XObject.extend(Scope, {
 })
 // init the scope constants..
 Scope.init();
\ No newline at end of file
+Scope.gid = 0;
\ No newline at end of file
index 1b315b0..d608dbd 100644 (file)
@@ -1,11 +1,28 @@
 //<Script type="text/javascript">
 
-Scope = imports['JSDOC/Scope.js'].Scope;
-
+Scope = imports.Scope.Scope;
+TokenStream = imports.TokenStream.TokenStream;
 /**
 * Scope stuff
 * 
 * // FIXME - I need this to do next() without doccomments..
+* 
+* 
+* 
+* Need to make this alot simpler...
+* 
+* so debugging is possible.
+* 
+* 
+* at present it just runs along the stream and finds stuff then calls parseExpr .. etc,,
+* 
+* 
+* It would be better to parse blocks of code rather than the whole stream..
+* 
+* 
+* 
+* 
+* 
 */
 
 ScopeParser = function(ts) {
@@ -124,7 +141,7 @@ ScopeParser.prototype = {
         this.braceNesting = 0;
         this.scopes = [];
         
-        
+       // print(JSON.stringify(this.ts.tokens, null,4));
         
         
         this.globalScope = new  Scope(-1, false, -1, '');
@@ -187,9 +204,8 @@ ScopeParser.prototype = {
             //println("<B>LOG:</B>" + str + "<BR/>");
     },
 
-
-
-
+     
+    
 
 
     parseScope : function(scope) // parse a token stream..
@@ -201,17 +217,33 @@ ScopeParser.prototype = {
         
         var identifier;
 
-        var expressionBraceNesting = this.braceNesting;
+        var expressionBraceNesting = this.braceNesting + 0;
         
         var parensNesting = 0;
         
         var isObjectLitAr = [ false ];
         var isInObjectLitAr;
-        this.scopes.push(scope);
+        thisScope = scope;
+        if (thisScope && thisScope.gid != this.scopes[this.scopes.length-1]) {
+            this.scopes.push(scope);
+        } else {
+            thisScope = this.scopes[this.scopes.length-1]
+        }
+       
+        //var scopeIndent = ''; 
+        //this.scopes.forEach(function() {
+        //    scopeIndent += '   '; 
+        //});
+        //print(">> ENTER SCOPE");
+        
+        
+        
+        
         token = this.ts.lookTok(1);
         while (token) {
           //  this.timerPrint("parseScope AFTER lookT: " + token.toString()); 
-             
+            //this.dumpToken(token , this.scopes, this.braceNesting);
+            //print('SCOPE:' + token.toString());
             //this.log(token.data);
             if (token.type == 'NAME') {
             //    print('*' + token.data);
@@ -219,12 +251,14 @@ ScopeParser.prototype = {
             switch(token.type + '.' + token.name) {
                 case "KEYW.VAR":
                 case "KEYW.CONST": // not really relivant as it's only mozzy that does this.
+                    //print('SCOPE-VAR:' + token.toString());
+                    var vstart = this.ts.cursor +1;
                     
                     //this.log("parseScope GOT VAR/CONST : " + token.toString()); 
                     while (true) {
                         token = this.ts.nextTok();
-                        !this.debug|| print( token.toString());
-                      
+                        //!this.debug|| print( token.toString());
+                        //print('SCOPE-VAR-VAL:' + JSON.stringify(token, null, 4));
                         if (!token) { // can return false at EOF!
                             break;
                         }
@@ -232,7 +266,7 @@ ScopeParser.prototype = {
                             continue;
                         }
                         //this.logR("parseScope GOT VAR  : <B>" + token.toString() + "</B>"); 
-                        if (token.type !="NAME") {
+                        if (token.type != "NAME") {
                             for(var i = Math.max(this.ts.cursor-10,0); i < this.ts.cursor+1; i++) {
                                 print(this.ts.tokens[i].toString());
                             }
@@ -243,10 +277,10 @@ ScopeParser.prototype = {
                         
 
                         if (this.mode == "BUILDING_SYMBOL_TREE") {
-                            identifier = scope.getIdentifier(token.data) ;
+                            identifier = thisScope.getIdentifier(token.data,token) ;
                             
                             if (identifier == false) {
-                                scope.declareIdentifier(token.data, token);
+                                thisScope.declareIdentifier(token.data, token);
                             } else {
                                 token.identifier = identifier;
                                 this.warn("(SCOPE) The variable " + token.data  + ' (line:' + token.line + ")  has already been declared in the same scope...");
@@ -265,7 +299,23 @@ ScopeParser.prototype = {
                             break;
                         } else {
                             //var bn = this.braceNesting;
-                            this.parseExpression();
+                            var bn = this.braceNesting;
+                            var nts = [];
+                            while (true) {
+                                if (!token || token.type == 'VOID' || token.data == ',') {
+                                    break;
+                                }
+                                nts.push(token);
+                                token = this.ts.nextTok();
+                            }
+                            if (nts.length) {
+                                var TS = this.ts;
+                                this.ts = new TokenStream(nts);
+                                this.parseExpression();
+                                this.ts = TS;
+                            }
+                               
+                            this.braceNesting = bn;
                             //this.braceNesting = bn;
                             //this.logR("parseScope DONE  : <B>ParseExpression</B> - tok is:" + this.ts.lookT(0).toString()); 
                             
@@ -276,8 +326,14 @@ ScopeParser.prototype = {
                             }
                         }
                     }
+                    
+                    //print("VAR:")
+                    //this.ts.dump(vstart , this.ts.cursor);
+                    
                     break;
                 case "KEYW.FUNCTION":
+                    //if (this.mode == 'BUILDING_SYMBOL_TREE') 
+                    //    print('SCOPE-FUNC:' + JSON.stringify(token,null,4));
                     //println("<i>"+token.data+"</i>");
                      var bn = this.braceNesting;
                     this.parseFunctionDeclaration();
@@ -285,14 +341,57 @@ ScopeParser.prototype = {
                     break;
 
                 case "PUNC.LEFT_CURLY": // {
+                case "PUNC.LEFT_PAREN": // (    
+                case "PUNC.LEFT_BRACE": // [
+                    //print('SCOPE-CURLY/PAREN:' + token.toString());
                     //println("<i>"+token.data+"</i>");
-                    isObjectLitAr.push(false);
-                    this.braceNesting++;
+                    var curTS = this.ts;
+                    if (token.props) {
+                        
+                        for (var prop in token.props) {
+                            
+                            
+                          //  print('SCOPE-PROPS:' + JSON.stringify(token.props[prop],null,4));
+                            if (token.props[prop].val[0].data == 'function') {
+                                // parse a function..
+                                this.ts = new TokenStream(token.props[prop].val);
+                                this.ts.nextTok();
+                                this.parseFunctionDeclaration();
+                                
+                                continue;
+                            }
+                            // key value..
+                            
+                            this.ts = new TokenStream(token.props[prop].val);
+                            this.parseExpression();
+                            
+                        }
+                        this.ts = curTS;
+                        
+                        // it's an object literal..
+                        // the values could be replaced..
+                        break;
+                    }
+                    
+                    
+                    var _this = this;
+                    token.items.forEach(function(expr) {
+                          _this.ts = new TokenStream(expr);
+                          _this.parseExpression()
+                    });
+                    this.ts = curTS;
+                    //print("NOT PROPS"); Seed.quit();
+                    
+                    //isObjectLitAr.push(false);
+                    //this.braceNesting++;
                     
                     //print(">>>>>> OBJLIT PUSH(false)" + this.braceNesting);
                     break;
 
                 case "PUNC.RIGHT_CURLY": // }
+                    //print("<< EXIT SCOPE");
+                    return;
+                /*
                     //println("<i>"+token.data+"</i>");
                     this.braceNesting--;
                     isObjectLitAr.pop();
@@ -307,12 +406,13 @@ ScopeParser.prototype = {
                             this.ts.nextTok();
                         }
                         
-                        //print("<<<<<<<EXIT SCOPE" +this.scopes.length);
+                        print("<<<<<<<EXIT SCOPE" +this.scopes.length);
                         return;
                     }
                     break;
-
+*/
                 case "KEYW.WITH":
+                    //print('SCOPE-WITH:' + token.toString());
                     //println("<i>"+token.data+"</i>");   
                     if (this.mode == "BUILDING_SYMBOL_TREE") {
                         // Inside a 'with' block, it is impossible to figure out
@@ -320,12 +420,13 @@ ScopeParser.prototype = {
                         // object member. As a consequence, the only thing we can
                         // do is turn the obfuscation off for the highest scope
                         // containing the 'with' block.
-                        this.protectScopeFromObfuscation(scope);
+                        this.protectScopeFromObfuscation(thisScope);
                         this.warn("Using 'with' is not recommended." + (this.munge ? " Moreover, using 'with' reduces the level of compression!" : ""), true);
                     }
                     break;
 
                 case "KEYW.CATCH":
+                    //print('SCOPE-CATCH:' + token.toString());
                     //println("<i>"+token.data+"</i>");
                     this.parseCatch();
                     break;
@@ -340,7 +441,9 @@ ScopeParser.prototype = {
                 
                 case "STRN.DOUBLE_QUOTE": // used for object lit detection..
                 case "STRN.SINGLE_QUOTE":
+                  //  print('SCOPE-STRING:' + token.toString());
                     //println("<i>"+token.data+"</i>");
+
                     if (this.ts.lookTok(-1).data == '{' && this.ts.lookTok(1).data == ':') {
                         // then we are in an object lit.. -> we need to flag the brace as such...
                         isObjectLitAr.pop();
@@ -368,27 +471,12 @@ ScopeParser.prototype = {
                     break;
                 
                 case "NAME.NAME":
-                
+                    //print('SCOPE-NAME:' + token.toString());
                     //print("DEAL WITH NAME:");
                     // got identifier..
                     
                     // look for  { ** : <- indicates obj literal.. ** this could occur with numbers ..
-                    if ((this.ts.lookTok(-1).data == "{") && (this.ts.lookTok(1).data == ":")) {
-                        isObjectLitAr.pop();
-                        isObjectLitAr.push(true);
-                        //print(">>>>>> OBJLIT REPUSH(true)");
-                        //println("<i>"+token.data+"</i>");
-                        break;
-                    }
-                   // print("DEAL WITH obj lit:");
-                    isInObjectLitAr = isObjectLitAr[isObjectLitAr.length-1];
-                    
-                    if (isInObjectLitAr && (this.ts.lookTok(1).data == ":") && (this.ts.lookTok(-1).data == ",")) {
-                        // skip, it's an object lit key..
-                        //println("<i>"+token.data+"</i>");
-                        break;
-                    }
-                    
+                     
                     
                     // skip anyting with "." before it..!!
                      
@@ -397,7 +485,12 @@ ScopeParser.prototype = {
                         //println("<i>"+token.data+"</i>");
                         break;
                     }
+                    //print("SYMBOL: " + token.toString());
+                    
                     symbol = token.data;
+                    if (symbol == 'this') {
+                        break;
+                    }
                     if (this.mode == 'PASS2_SYMBOL_TREE') {
                         
                         //println("GOT IDENT: -2 : " + this.ts.lookT(-2).toString() + " <BR> ..... -1 :  " +  this.ts.lookT(-1).toString() + " <BR> "); 
@@ -407,7 +500,7 @@ ScopeParser.prototype = {
                         //println("GOT IDENT: <B>" + symbol + "</B><BR/>");
                              
                             //println("GOT IDENT (2): <B>" + symbol + "</B><BR/>");
-                        identifier = this.getIdentifier(symbol, scope);
+                        identifier = this.getIdentifier(symbol, thisScope, token);
                         
                         if (identifier == false) {
 // BUG!find out where builtin is defined...
@@ -433,23 +526,29 @@ ScopeParser.prototype = {
                     if (token.type != 'KEYW') {
                         break;
                     }
+                    //print('SCOPE-KEYW:' + token.toString());
                    // print("Check eval:");
                 
                     symbol = token.data;
                     
                      if (this.mode == 'BUILDING_SYMBOL_TREE') {
 
-                        if (symbol == "eval") {
+                        if (token.name == "EVAL") {
+                            
+                            //print(JSON.stringify(token, null,4));
                             // look back one and see if we can find a comment!!!
-                            if (this.ts.look(-1).type == "COMM") {
+                            //if (this.ts.look(-1).type == "COMM") {
+                            if (token.prefix && token.prefix.match(/eval/)) {
                                 // look for eval:var:noreplace\n
+                                //print("MATCH!?");
                                 var _t = this;
-                                this.ts.look(-1).data.replace(/eval:var:([a-z_]+)/ig, function(m, a) {
-                                    
-                                    var hi = _t.getIdentifier(a, scope);
+                                token.prefix.replace(/eval:var:([a-z_]+)/ig, function(m, a) {
+                                    //print("GOT: " + a);
+                                    var hi = _t.getIdentifier(a, thisScope, token);
                                    // println("PROTECT "+a+" from munge" + (hi ? "FOUND" : "MISSING"));
                                     if (hi) {
-                                     //   println("PROTECT "+a+" from munge");
+                                      //  print("PROTECT "+a+" from munge");
+                                        //print(JSON.stringify(hi,null,4));
                                         hi.toMunge = false;
                                     }
                                     
@@ -459,7 +558,7 @@ ScopeParser.prototype = {
                             } else {
                                 
                             
-                                this.protectScopeFromObfuscation(scope);
+                                this.protectScopeFromObfuscation(thisScope);
                                 this.warn("Using 'eval' is not recommended. (use  eval:var:noreplace in comments to optimize) " + (this.munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
                             }
 
@@ -472,15 +571,16 @@ ScopeParser.prototype = {
             } // end switch
             
             
-            //this.timerPrint("parseScope TOK : " + token.toString()); 
+            //print("parseScope TOK : " + token.toString()); 
             token = this.ts.nextTok();
             //if (this.ts.nextT()) break;
             
         }
+        //print("<<< EXIT SCOPE");
         //print("<<<<<<<EXIT SCOPE ERR?" +this.scopes.length);
     },
 
-
+    expN : 0,
     parseExpression : function() {
 
         // Parse the expression until we encounter a comma or a semi-colon
@@ -488,124 +588,163 @@ ScopeParser.prototype = {
         // Parse functions if any...
         //println("<i>EXP</i><BR/>");
         !this.debug || print("PARSE EXPR");
+        this.expN++;
+         
+        // for printing stuff..
+       
+        
+        
         var symbol;
         var token;
         var currentScope;
         var identifier;
 
-        var expressionBraceNesting = this.braceNesting;
+        var expressionBraceNesting = this.braceNesting + 0;
         var bracketNesting = 0;
         var parensNesting = 0;
         var isInObjectLitAr;
         var isObjectLitAr = [ false ];
-        while (token = this.ts.lookTok()) {
+        
+        currentScope = this.scopes[this.scopes.length-1];
+            
+        
+        //print(scopeIndent + ">> ENTER EXPRESSION" + this.expN);
+        while (token = this.ts.nextTok()) {
      
-
+        
+            
+           /*
+            // moved out of loop?
+           currentScope = this.scopes[this.scopes.length-1];
+            
+            var scopeIndent = ''; 
+            this.scopes.forEach(function() {
+                scopeIndent += '   '; 
+            });
+           */ 
+           
+           //this.dumpToken(token,  this.scopes, this.braceNesting );
+           //print('EXPR' +  token.toString());
             
-            currentScope = this.scopes[this.scopes.length-1];
             
             //println("<i>"+token.data+"</i>");
             //this.log("EXP:" + token.data);
             switch (token.type) {
                 case 'PUNC':
+                    //print("EXPR-PUNC:" + token.toString());
+                    
                     switch(token.data) {
                          
                         case ';':
+                            //print("<< EXIT EXPRESSION");
+                            break;
+
                         case ',':
-                            if (this.braceNesting == expressionBraceNesting &&
-                                    bracketNesting == 0 &&
-                                    parensNesting == 0) {
-                                
-                                return;
-                            }
+                            
                             break;
 
                        
-
+                        case '(': //Token.LP:
                         case '{': //Token.LC:
-                            isObjectLitAr.push(false);
+                        case '[': //Token.LB:
+                            //print('SCOPE-CURLY/PAREN/BRACE:' + token.toString());
+                           // print('SCOPE-CURLY/PAREN/BRACE:' + JSON.stringify(token, null,4));
+                            //println("<i>"+token.data+"</i>");
+                            var curTS = this.ts;
+                            if (token.props) {
+                                
+                                for (var prop in token.props) {
+                                    if (!token.props[prop].val.length) {
+                                        print(JSON.stringify(token.props, null,4));
+                                    }
+                                    
+                                    if (token.props[prop].val[0].data == 'function') {
+                                        // parse a function..
+                                        this.ts = new TokenStream(token.props[prop].val);
+                                        this.ts.nextTok();
+                                        this.parseFunctionDeclaration();
+                                        continue;
+                                    }
+                                    // key value..
+                                    
+                                    this.ts = new TokenStream(token.props[prop].val);
+                                    this.parseExpression();
+                                    
+                                }
+                                this.ts = curTS;
+                                
+                                // it's an object literal..
+                                // the values could be replaced..
+                                break;
+                            }
+                            
                             
-                            this.braceNesting++;
+                            var _this = this;
+                            token.items.forEach(function(expr) {
+                                  _this.ts = new TokenStream(expr);
+                                  _this.parseExpression()
+                            });
+                            this.ts = curTS;
+                        
+                        
+                    
                             ///print(">>>>> EXP PUSH(false)"+this.braceNesting);
                             break;
 
-                        case '}': //Token.RC:
-                            this.braceNesting--;
-                            isObjectLitAr.pop();
-                            //print(">>>>> EXP POP" + this.braceNesting);    
-                           // assert braceNesting >= expressionBraceNesting;
-                            break;
-
-                        case '[': //Token.LB:
-                            bracketNesting++;
-                            break;
-
+                       
+                        
+                         
+                            
+                        case ')': //Token.RP:
                         case ']': //Token.RB:
-                            bracketNesting--;
-                            break;
-
-                        case '(': //Token.LP:
+                        case '}': //Token.RB:
+                            //print("<< EXIT EXPRESSION");
+                            return;
+                           
+             
                             parensNesting++;
                             break;
 
-                        case ')': //Token.RP:
-                            parensNesting--;
-                            break;
+                        
+                            
                     }
                     break;
                     
                 case 'STRN': // used for object lit detection..
-                    if (this.ts.lookTok(-1).data == "{" && this.ts.lookTok(1).data == ":" ) {
-                        // then we are in an object lit.. -> we need to flag the brace as such...
-                        isObjectLitAr.pop();
-                        isObjectLitAr.push(true);
-                        //print(">>>>> EXP PUSH(true)");
-                    }
-                    
-                    
+                    //if (this.mode == 'BUILDING_SYMBOL_TREE')    
+                        //print("EXPR-STR:" + JSON.stringify(token, null, 4));
+               
                      
-                    isInObjectLitAr = isObjectLitAr[isObjectLitAr.length-1];
-                    if (isInObjectLitAr &&  this.ts.lookTok(1).data == ":"  &&
-                        ( this.ts.lookTok(-1).data == "{"  ||  this.ts.lookTok(-1).data == "," )) {
-                        // see if we can replace..
-                        // remove the quotes..
-                        var str = token.data.substring(1,token.data.length-1);
-                        if (/^[a-z_]+$/i.test(str) && ScopeParser.idents.indexOf(str) < 0) {
-                            token.outData = str;
-                        }
-                        
-                         
-                        
-                    }
-                    
                     break;
                 
                       
              
                 case 'NAME':
-               
-                    symbol = token.data;
-                  
-                    if (this.ts.look(0).data == "{"  && this.ts.lookTok(2).data == ":") {
-                        // then we are in an object lit.. -> we need to flag the brace as such...
-                        isObjectLitAr.pop();
-                        isObjectLitAr.push(true);
-                         //print(">>>>> EXP  PUSH(true)");
-                        break;
-                    }
-                    isInObjectLitAr = isObjectLitAr[isObjectLitAr.length-1];
-                    if (isInObjectLitAr && this.ts.lookTok(0).data == "," && this.ts.lookTok(2).data == ":") {
-                        break;
+                    if (this.mode == 'BUILDING_SYMBOL_TREE') {
+                        
+                        //print("EXPR-NAME:" + JSON.stringify(token, null, 4));
+                    } else {
+                        //print("EXPR-NAME:" + token.toString());
                     }
-                    //print(this.ts.lookTok(0).data);
-                    if (this.ts.lookTok(0).data == ".") {
+                    symbol = token.data;
+                    //print("in NAME = " + token.toString());
+                    //print("in NAME 0: " + this.ts.look(0).toString());
+                    //print("in NAME 2: " + this.ts.lookTok(2).toString());
+                    
+                    //print(this.ts.lookTok(-1).data);
+                    // prefixed with '.'
+                    if (this.ts.lookTok(-1).data == ".") {
                         //skip '.'
                         break;
                     }
+                    if (symbol == 'this') {
+                        break;
+                       }
                     
-                     if (this.mode == 'PASS2_SYMBOL_TREE') {
+                    if (this.mode == 'PASS2_SYMBOL_TREE') {
 
-                        identifier = this.getIdentifier(symbol, currentScope);
+                        identifier = this.getIdentifier(symbol, currentScope, token);
                         //println("<B>??</B>");
                         if (identifier == false) {
 
@@ -616,8 +755,10 @@ ScopeParser.prototype = {
                                 // any conflict with other munged symbols.
                                 this.globalScope.declareIdentifier(symbol, token);
                                 this.warn("Found an undeclared symbol: " + symbol + ' (line:' + token.line + ')', true);
+                                //print("Found an undeclared symbol: " + symbol + ' (line:' + token.line + ')');
+                                //throw "OOPS";
                             } else {
-                                //println("undeclared")
+                                //print("undeclared:" + token.toString())
                             }
                             
                             
@@ -634,8 +775,11 @@ ScopeParser.prototype = {
                     
                     
                     //println("<B>EID</B>");
-                 case 'KEYW':   
-                 
+                case 'KEYW':   
+                    //if (this.mode == 'BUILDING_SYMBOL_TREE') 
+                    //    print("EXPR-KEYW:" + JSON.stringify(token, null, 4));
+                    
+                    //print('EXPR-KEYW:' + token.toString());
                     if (token.name == "FUNCTION") {
                         
                         this.parseFunctionDeclaration();
@@ -646,13 +790,19 @@ ScopeParser.prototype = {
              
                     symbol = token.data;
                     if (this.mode == 'BUILDING_SYMBOL_TREE') {
-
-                        if (symbol == "eval") {
-                            if (this.ts.look(-1).type == 'COMM') {
+                        
+                        if (token.name == "EVAL") {
+                            //print(JSON.stringify(token,null,4));
+                            if (token.prefix && token.prefix.match(/eval:var:/g)) {
                                 // look for eval:var:noreplace\n
+                               // print("GOT MATCH?");
                                 var _t = this;
-                                this.ts.look(-1).data.replace(/eval:var:([a-z]+)/ig, function(m, a) {
-                                    var hi = _t.getIdentifier(a, currentScope);
+                                token.prefix.replace(/eval:var:([a-z]+)/ig, function(m, a) {
+                                    
+                                    //print("PROTECT: " + a);
+                                    
+                                    
+                                    var hi = _t.getIdentifier(a, currentScope, token);
                                    //println("PROTECT "+a+" from munge" + (hi ? "FOUND" : "MISSING"));
                                     if (hi) {
                                       //  println("PROTECT "+a+" from munge");
@@ -671,10 +821,15 @@ ScopeParser.prototype = {
                         }
                         break;
                     } 
-                   
+                default:
+                    //if (this.mode == 'BUILDING_SYMBOL_TREE') 
+                    //    print("EXPR-SKIP:" + JSON.stringify(token, null, 4));
+                    break;
             }
-            if (!this.ts.nextTok()) break;
+            
         }
+        //print("<< EXIT EXPRESSION");
+        this.expN--;
     },
 
 
@@ -684,40 +839,44 @@ ScopeParser.prototype = {
         var token;
         var currentScope;
         var identifier;
-
+        
         //token = getToken(-1);
         //assert token.getType() == Token.CATCH;
         token = this.ts.nextTok();
+        
+        //print(JSON.stringify(token,null,4));
         //assert token.getType() == Token.LP; (
-        token = this.ts.nextTok();
+        //token = this.ts.nextTok();
         //assert token.getType() == Token.NAME;
         
-        symbol = token.data;
+        symbol = token.items[0][0].data;
         currentScope = this.scopes[this.scopes.length-1];
 
         if (this.mode == 'BUILDING_SYMBOL_TREE') {
             // We must declare the exception identifier in the containing function
             // scope to avoid errors related to the obfuscation process. No need to
             // display a warning if the symbol was already declared here...
-            currentScope.declareIdentifier(symbol, token);
+            currentScope.declareIdentifier(symbol, token.items[0][0]);
         } else {
             //?? why inc the refcount?? - that should be set when building the tree???
-            identifier = this.getIdentifier(symbol, currentScope);
+            identifier = this.getIdentifier(symbol, currentScope, token.items[0][0]);
             identifier.refcount++;
         }
-
+        
         token = this.ts.nextTok();
         //assert token.getType() == Token.RP; // )
     },
     
     parseFunctionDeclaration : function() 
     {
-       // print("PARSE FUNCTION");
+        //print("PARSE FUNCTION");
         var symbol;
         var token;
         var currentScope  = false; 
         var fnScope = false;
         var identifier;
+        var b4braceNesting = this.braceNesting + 0;
+        
         //this.logR("<B>PARSING FUNCTION</B>");
         currentScope = this.scopes[this.scopes.length-1];
 
@@ -726,33 +885,45 @@ ScopeParser.prototype = {
             if (this.mode == 'BUILDING_SYMBOL_TREE') {
                 // Get the name of the function and declare it in the current scope.
                 symbol = token.data;
-                if (currentScope.getIdentifier(symbol) != false) {
+                if (currentScope.getIdentifier(symbol,token) != false) {
                     this.warn("The function " + symbol + " has already been declared in the same scope...", true);
                 }
                 currentScope.declareIdentifier(symbol,token);
             }
             token =  this.ts.nextTok();
         }
-
+        
+        
+        // return function() {.... 
+        while (token.data != "(") {
+            print(token.toString());
+            token =  this.ts.nextTok();
+            
+            
+            
+        }
+        
+        
         //assert token.getType() == Token.LP;
         if (this.mode == 'BUILDING_SYMBOL_TREE') {
-            fnScope = new Scope(this.braceNesting, currentScope, token.n, '');
+            fnScope = new Scope(1, currentScope, token.n, '', token);
             
             //println("STORING SCOPE" + this.ts.cursor);
             
-            this.indexedScopes[this.ts.cursor] = fnScope;
+            this.indexedScopes[token.id] = fnScope;
             
         } else {
             //qln("FETCHING SCOPE" + this.ts.cursor);
-            fnScope = this.indexedScopes[this.ts.cursor];
-          
+            fnScope = this.indexedScopes[token.id];
         }
-        
+        //if (this.mode == 'BUILDING_SYMBOL_TREE') 
+        //  print('FUNC-PARSE:' + JSON.stringify(token,null,4));
         // Parse function arguments.
-        var argpos = 0;
-        while (this.ts.lookTok().data != ')') { //(token = consumeToken()).getType() != Token.RP) {
-            token = this.ts.nextTok();
-           // print ("FUNC ARGS: " + token.toString())
+        var args = token.items;
+        for (var argpos =0; argpos < args.length; argpos++) {
+             
+            token = args[argpos][0];
+            //print ("FUNC ARGS: " + token.toString())
             //assert token.getType() == Token.NAME ||
             //        token.getType() == Token.COMMA;
             if (token.type == 'NAME' && this.mode == 'BUILDING_SYMBOL_TREE') {
@@ -762,68 +933,37 @@ ScopeParser.prototype = {
                     // Exception for Prototype 1.6...
                     identifier.preventMunging();
                 }
-                argpos++;
+                //argpos++;
             }
         }
-
+        
         token = this.ts.nextTok();
+        //print('FUNC-BODY:' + JSON.stringify(token.items,null,4));
+        //Seed.quit();
+        //print(token.toString());
         // assert token.getType() == Token.LC;
-        this.braceNesting++;
-
-        token = this.ts.nextTok();
-        if (token.type == "STRN" && this.ts.lookTok(1).data == ';') {
-            /*
+        //this.braceNesting++;
+        
+        //token = this.ts.nextTok();
+        //print(token.toString());
+        var outTS = this.ts;
+        var _this = this;
+        token.items.forEach(function(tar) {
+            _this.ts = new TokenStream(tar);
+            _this.parseScope(fnScope);
             
-            NOT SUPPORTED YET!?!!?!
             
-            // This is a hint. Hints are empty statements that look like
-            // "localvar1:nomunge, localvar2:nomunge"; They allow developers
-            // to prevent specific symbols from getting obfuscated (some heretic
-            // implementations, such as Prototype 1.6, require specific variable
-            // names, such as $super for example, in order to work appropriately.
-            // Note: right now, only "nomunge" is supported in the right hand side
-            // of a hint. However, in the future, the right hand side may contain
-            // other values.
-            consumeToken();
-            String hints = token.getValue();
-            // Remove the leading and trailing quotes...
-            hints = hints.substring(1, hints.length() - 1).trim();
-            StringTokenizer st1 = new StringTokenizer(hints, ",");
-            while (st1.hasMoreTokens()) {
-                String hint = st1.nextToken();
-                int idx = hint.indexOf(':');
-                if (idx <= 0 || idx >= hint.length() - 1) {
-                    if (mode == BUILDING_SYMBOL_TREE) {
-                        // No need to report the error twice, hence the test...
-                        this.warn("Invalid hint syntax: " + hint, true);
-                    }
-                    break;
-                }
-                String variableName = hint.substring(0, idx).trim();
-                String variableType = hint.substring(idx + 1).trim();
-                if (mode == BUILDING_SYMBOL_TREE) {
-                    fnScope.addHint(variableName, variableType);
-                } else if (mode == CHECKING_SYMBOL_TREE) {
-                    identifier = fnScope.getIdentifier(variableName);
-                    if (identifier != null) {
-                        if (variableType.equals("nomunge")) {
-                            identifier.preventMunging();
-                        } else {
-                            this.warn("Unsupported hint value: " + hint, true);
-                        }
-                    } else {
-                        this.warn("Hint refers to an unknown identifier: " + hint, true);
-                    }
-                }
-            }
-            */
-        }
-
-        this.parseScope(fnScope);
+        });
+        
+        //print(JSON.stringify(this.ts,null,4));
+        //this.parseScope(fnScope);
+        this.ts = outTS;
         // now pop it off the stack!!!
        
-        
-        
+        //this.braceNesting = b4braceNesting;
+        //print("ENDFN -1: " + this.ts.lookTok(-1).toString());
+        //print("ENDFN 0: " + this.ts.lookTok(0).toString());
+        //print("ENDFN 1: " + this.ts.lookTok(1).toString());
     },
     
     protectScopeFromObfuscation : function(scope) {
@@ -844,10 +984,10 @@ ScopeParser.prototype = {
         scope.preventMunging();
     },
     
-    getIdentifier: function(symbol, scope) {
+    getIdentifier: function(symbol, scope, token) {
         var identifier;
         while (scope != false) {
-            identifier = scope.getIdentifier(symbol);
+            identifier = scope.getIdentifier(symbol, token);
             //println("ScopeParser.getIdentgetUsedSymbols("+symbol+")=" + scope.getUsedSymbols().join(','));
             if (identifier) {
                 return identifier;
diff --git a/JSDOC/Symbol.js b/JSDOC/Symbol.js
new file mode 100644 (file)
index 0000000..3620491
--- /dev/null
@@ -0,0 +1,828 @@
+//<script type="text/javascript">
+
+XObject         = imports.XObject.XObject;
+
+SymbolSet       = imports.SymbolSet.SymbolSet;
+//Parser          = imports.Parser.Parser;
+DocComment      = imports.DocComment.DocComment;
+DocTag          = imports.DocTag.DocTag;
+/**
+       Create a new Symbol.
+       @class Represents a symbol in the source code.
+ */
+Symbol = XObject.define(
+    function() {
+        this.init();
+        if (arguments.length) this.populate.apply(this, arguments);
+        
+    },
+    Object,
+    {
+        
+        
+        name : "",
+        defaultValue : "",
+        params : [],
+        $args : [], // original arguments used when constructing.
+        addOn : "",
+        alias : "",
+        augments : [], // Doctag[]
+        author : "",
+        classDesc : "",
+        comment : {},
+        deprecated : "",
+        desc : "",
+        //events : false,
+        example : "",
+        exceptions : [],  // Doctag[]
+        inherits : [],  // Doctag[]
+        //inheritsFrom : [],
+        isa : "OBJECT", // OBJECT//FUNCTION
+        isEvent : false,
+        isConstant : false,
+        isIgnored : false,
+        isInner : false,
+        isNamespace : false,
+        isPrivate : false,
+        isStatic : false,
+        memberOf : "",
+        methods : [], // Symbol[]
+        _name : "",
+        _params : [], //Doctag[]
+        properties : [], //Doctag[]
+        requires : [],  //Doctag[]
+        returns : [], //Doctag[]
+        see : [], //Doctag[]
+        since : "",
+        srcFile : {},
+        type : "",
+        version : "",
+        childClasses : [],
+        cfgs : {},
+        
+        
+            
+        
+        toJSON : function()
+        {
+            
+           
+            var ret = { '*object' : 'Symbol' };
+            for (var i in this) {
+                if (Symbol.hide.indexOf(i) > -1) {
+                    continue;
+                }
+                switch (typeof(this[i])) {
+                    case 'function':
+                        continue;
+                    case 'object':
+                        switch(i) {
+                            //arrays..
+                            case 'params' : 
+                            case 'augments' :                             
+                            case 'exceptions' :  
+                            case 'inherits' :
+                            case 'methods' :
+                            case '_params': 
+                            case 'properties': 
+                            case 'requires':
+                            case 'returns':
+                            case 'see':
+                            case 'cfgs': // key val of doctags..
+                            case 'comment' :
+                                ret[i] = this[i]
+                                continue; 
+                            
+                            //skip
+                            case 'inheritsFrom':
+                            case 'childClasses':
+                                continue;
+            
+                            default:
+                                print("object? :" + i);
+                                Seed.quit();
+                        }
+                        
+                        
+                    case 'string':
+                    case 'number':
+                    case 'boolean':
+                        ret[i] = this[i]; continue;
+                    default:
+                        print("unknown type:" + typeof(this[i]));
+                        Seed.quit();
+                   }
+            }
+            return ret;
+            
+        },
+        
+        init : function() 
+        {
+            // only initialize arrays / objects..
+            this.params = [];
+            this.$args = [];
+            
+            //this.events = [];
+            this.exceptions = [];
+            this.inherits = [];
+            //
+            this.isa = "OBJECT"; // OBJECT//FUNCTION
+            this.methods = [];
+            this._params = [];
+            this.properties = [];
+            this.requires = [];
+            this.returns = [];
+            this.see = [];
+            this.srcFile = {};
+            
+            
+            this.cfgs = {};
+            // derived later?
+            this.inheritsFrom = [];
+            this.childClasses = [];
+            
+            this.comment = new DocComment();
+            this.comment.isUserComment =  false;
+            
+               
+        },
+
+        serialize : function() {
+            var keys = [];
+            for (var p in this) {
+                keys.push (p);
+            }
+            keys = keys.sort();
+            
+            var out = "";
+            for (var i in keys) {
+                if (typeof this[keys[i]] == "function") continue;
+                out += "     " +keys[i]+" => "+
+                    (   
+                        (typeof(this[keys[i]]) != "object") ?  
+                            this[keys[i]] :
+                            "[" +typeof(this[keys[i]])+"]"
+                    ) + 
+                    ",\n";
+            }
+            return "\n{\n" + out + "}\n";
+        },
+
+        clone : function() {
+            var clone = new Symbol();
+            clone.populate.apply(clone, this.$args); // repopulate using the original arguments
+            clone.srcFile = this.srcFile; // not the current srcFile, the one when the original was made
+            return clone;
+        },
+
+
+
+
+        //__defineSetter__("name",
+        setName  : function(n) { 
+                n = n.replace(/^_global_[.#-]/, ""); 
+                n = n.replace(/\.prototype\.?/g, '#'); 
+                 n = n.replace(/#$/g, ''); 
+                this._name = n;
+                this.name = n; // real!
+            },
+        //);
+        //__defineGetter__("name",
+        getName : function() { return this._name; },
+        //);
+        //__defineSetter__("params", 
+        setParams  :function(v) {
+                for (var i = 0, l = v.length; i < l; i++) {
+                    if (v[i].constructor != DocTag) { // may be a generic object parsed from signature, like {type:..., name:...}
+                        var ty = v[i].hasOwnProperty('type') ? v[i].type : '';
+                        this._params[i] = new DocTag(
+                            "param"+((ty)?" {"+ty+"}":"")+" "+v[i].name);
+                    }
+                    else {
+                        this._params[i] = v[i];
+                    }
+                }
+                this.params = this._params;
+            },
+        //);
+
+
+        //__defineGetter__("params",
+        getParams : function() { return this._params; },
+        //);
+
+        populate : function(
+                /** String */ name,
+                /** Object[] */ params,
+                /** String */ isa,
+                /** DocComment */ comment
+        ) {
+            this.$args = arguments;
+            //println("Symbol created: " + isa + ":" + name);
+            this.setName(name);
+            this.alias = this.getName();
+            this.setParams(params);
+            this.isa = (isa == "VIRTUAL")? "OBJECT":isa;
+            this.comment = comment || new DocComment("");
+            this.srcFile = Symbol.srcFile;
+            
+           
+            
+            if (this.is("FILE") && !this.alias) this.alias = this.srcFile;
+
+            this.setTags();
+            
+            //if (typeof PluginManager != "undefined") {
+            //    PluginManager.run("onSymbol", this);
+            //}
+        },
+
+        setTags : function() {
+            // @author
+            var authors = this.comment.getTag("author");
+            if (authors.length) {
+                this.author = authors.map(function($){return $.desc;}).join(", ");
+            }
+            
+            /*~t
+                assert("testing Symbol");
+                
+                requires("../lib/JSDOC/DocComment.js");
+                requires("../frame/String.js");
+                requires("../lib/JSDOC/DocTag.js");
+
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@author Joe Smith*"+"/"));
+                assertEqual(sym.author, "Joe Smith", "@author tag, author is found.");
+            */
+            // @desc
+            var mth = this.comment.getTag("method");
+            if (mth.length) {
+                this.isa = "FUNCTION";
+            }
+            // @desc
+            var descs = this.comment.getTag("desc");
+            if (descs.length) {
+                this.desc = descs.map(function($){return $.desc;}).join("\n"); // multiple descriptions are concatenated into one
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@desc This is a description.*"+"/"));
+                assertEqual(sym.desc, "This is a description.", "@desc tag, description is found.");
+            */
+            
+            // @overview
+            if (this.is("FILE")) {
+                if (!this.alias) this.alias = this.srcFile;
+                
+                var overviews = this.comment.getTag("overview");
+                if (overviews.length) {
+                    this.desc = [this.desc].concat(overviews.map(function($){return $.desc;})).join("\n");
+                }
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@overview This is an overview.*"+"/"));
+                assertEqual(sym.desc, "\nThis is an overview.", "@overview tag, description is found.");
+            */
+            
+            // @since
+            var sinces = this.comment.getTag("since");
+            if (sinces.length) {
+                this.since = sinces.map(function($){return $.desc;}).join(", ");
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@since 1.01*"+"/"));
+                assertEqual(sym.since, "1.01", "@since tag, description is found.");
+            */
+            
+            // @constant
+            if (this.comment.getTag("constant").length) {
+                this.isConstant = true;
+                this.isa = 'OBJECT';
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@constant*"+"/"));
+                assertEqual(sym.isConstant, true, "@constant tag, isConstant set.");
+            */
+            
+            // @version
+            var versions = this.comment.getTag("version");
+            if (versions.length) {
+                this.version = versions.map(function($){return $.desc;}).join(", ");
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@version 2.0x*"+"/"));
+                assertEqual(sym.version, "2.0x", "@version tag, version is found.");
+            */
+            
+            // @deprecated
+            var deprecateds = this.comment.getTag("deprecated");
+            if (deprecateds.length) {
+                this.deprecated = deprecateds.map(function($){return $.desc;}).join("\n");
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@deprecated Use other method.*"+"/"));
+                assertEqual(sym.deprecated, "Use other method.", "@deprecated tag, desc is found.");
+            */
+            
+            // @example
+            var examples = this.comment.getTag("example");
+            if (examples.length) {
+                this.example = examples[0];
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@example This\n  is an example.*"+"/"));
+                assertEqual(sym.example, "This\n  is an example.", "@deprecated tag, desc is found.");
+            */
+            
+            // @see
+            var sees = this.comment.getTag("see");
+            if (sees.length) {
+                var thisSee = this.see;
+                sees.map(function($){thisSee.push($.desc);});
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FILE", new DocComment("/**@see The other thing.*"+"/"));
+                assertEqual(sym.see, "The other thing.", "@see tag, desc is found.");
+            */
+            
+            // @class
+            var classes = this.comment.getTag("class");
+            if (classes.length) {
+                this.isa = "CONSTRUCTOR";
+                this.classDesc = classes[0].desc; // desc can't apply to the constructor as there is none.
+                if (!this.classDesc) {
+                    this.classDesc = this.desc;
+                   }
+                
+                
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@class This describes the class.*"+"/"));
+                assertEqual(sym.isa, "CONSTRUCTOR", "@class tag, makes symbol a constructor.");
+                assertEqual(sym.classDesc, "This describes the class.", "@class tag, class description is found.");
+            */
+            
+            // @namespace
+            var namespaces = this.comment.getTag("namespace");
+            if (namespaces.length) {
+                this.classDesc = namespaces[0].desc+"\n"+this.desc; // desc can't apply to the constructor as there is none.
+                this.isNamespace = true;
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@namespace This describes the namespace.*"+"/"));
+                assertEqual(sym.classDesc, "This describes the namespace.\n", "@namespace tag, class description is found.");
+            */
+            
+            // @param
+            var params = this.comment.getTag("param");
+            if (params.length) {
+                // user-defined params overwrite those with same name defined by the parser
+                var thisParams = this.getParams();
+
+                if (thisParams.length == 0) { // none exist yet, so just bung all these user-defined params straight in
+                    this.setParams(params);
+                }
+                else { // need to overlay these user-defined params on to existing parser-defined params
+                    for (var i = 0, l = params.length; i < l; i++) {
+                        if (thisParams[i]) {
+                            if (params[i].type) thisParams[i].type = params[i].type;
+                            thisParams[i].name = params[i].name;
+                            thisParams[i].desc = params[i].desc;
+                            thisParams[i].isOptional = params[i].isOptional;
+                            thisParams[i].defaultValue = params[i].defaultValue;
+                        }
+                        else thisParams[i] = params[i];
+                    }
+                }
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [{type: "array", name: "pages"}], "FUNCTION", new DocComment("/**Description.*"+"/"));
+                assertEqual(sym.params.length, 1, "parser defined param is found.");
+                
+                sym = new Symbol("foo", [], "FUNCTION", new DocComment("/**Description.\n@param {array} pages*"+"/"));
+                assertEqual(sym.params.length, 1, "user defined param is found.");
+                assertEqual(sym.params[0].type, "array", "user defined param type is found.");
+                assertEqual(sym.params[0].name, "pages", "user defined param name is found.");
+                
+                sym = new Symbol("foo", [{type: "array", name: "pages"}], "FUNCTION", new DocComment("/**Description.\n@param {string} uid*"+"/"));
+                assertEqual(sym.params.length, 1, "user defined param overwrites parser defined param.");
+                assertEqual(sym.params[0].type, "string", "user defined param type overwrites parser defined param type.");
+                assertEqual(sym.params[0].name, "uid", "user defined param name overwrites parser defined param name.");
+            
+                sym = new Symbol("foo", [{type: "array", name: "pages"}, {type: "number", name: "count"}], "FUNCTION", new DocComment("/**Description.\n@param {string} uid*"+"/"));
+                assertEqual(sym.params.length, 2, "user defined params  overlay parser defined params.");
+                assertEqual(sym.params[1].type, "number", "user defined param type overlays parser defined param type.");
+                assertEqual(sym.params[1].name, "count", "user defined param name overlays parser defined param name.");
+
+                sym = new Symbol("foo", [], "FUNCTION", new DocComment("/**Description.\n@param {array} pages The pages description.*"+"/"));
+                assertEqual(sym.params.length, 1, "user defined param with description is found.");
+                assertEqual(sym.params[0].desc, "The pages description.", "user defined param description is found.");
+            */
+            
+            // @constructor
+            if (this.comment.getTag("constructor").length) {
+                this.isa = "CONSTRUCTOR";
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@constructor*"+"/"));
+                assertEqual(sym.isa, "CONSTRUCTOR", "@constructor tag, makes symbol a constructor.");
+            */
+            
+            // @static
+            if (this.comment.getTag("static").length) {
+                this.isStatic = true;
+                if (this.isa == "CONSTRUCTOR") {
+                    this.isNamespace = true;
+                }
+            }
+            
+                // @static
+            if (this.comment.getTag("singleton").length) {
+                this.isStatic = true;
+                //if (this.isa == "CONSTRUCTOR") {
+                //     this.isNamespace = true;
+                //}
+            }
+            
+            
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@static\n@constructor*"+"/"));
+                assertEqual(sym.isStatic, true, "@static tag, makes isStatic true.");
+                assertEqual(sym.isNamespace, true, "@static and @constructor tag, makes isNamespace true.");
+            */
+            
+            // @inner
+            if (this.comment.getTag("inner").length) {
+                this.isInner = true;
+                this.isStatic = false;
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@inner*"+"/"));
+                assertEqual(sym.isStatic, false, "@inner tag, makes isStatic false.");
+                assertEqual(sym.isInner, true, "@inner makes isInner true.");
+            */
+            
+            // @field
+            if (this.comment.getTag("field").length) {
+                this.isa = "OBJECT";
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "FUNCTION", new DocComment("/**@field*"+"/"));
+                assertEqual(sym.isa, "OBJECT", "@field tag, makes symbol an object.");
+            */
+            
+            // @function
+            if (this.comment.getTag("function").length) {
+                this.isa = "FUNCTION";
+            }
+            
+            // @param
+            if (this.comment.getTag("param").length && this.isa == "OBJECT" ) {
+                // change a property to a function..
+                this.isa = "FUNCTION";
+            }
+            
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@function*"+"/"));
+                assertEqual(sym.isa, "FUNCTION", "@function tag, makes symbol a function.");
+            */
+            
+            // @event
+            var events = this.comment.getTag("event");
+            if (events.length) {
+                this.isa = "FUNCTION";
+                this.isEvent = true;
+            }
+            
+            /*~t
+                var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@event*"+"/"));
+                assertEqual(sym.isa, "FUNCTION", "@event tag, makes symbol a function.");
+                assertEqual(sym.isEvent, true, "@event makes isEvent true.");
+            */
+            
+            // @name
+            var names = this.comment.getTag("name");
+            if (names.length) {
+                this.setName(names[0].desc);
+            }
+            
+            /*~t
+                // todo
+            */
+            
+            // @property
+            var properties = this.comment.getTag("property");
+            if (properties.length) {
+                thisProperties = this.properties;
+                for (var i = 0; i < properties.length; i++) {
+                    var property = new Symbol(this.alias+"#"+properties[i].name, [], "OBJECT", new DocComment("/**"+properties[i].desc+"\n@name "+properties[i].name+"\n@memberOf "+this.alias+"#*/"));
+                    // TODO: shouldn't the following happen in the addProperty method of Symbol?
+                    property.name = properties[i].name;
+                    property.memberOf = this.alias;
+                    if (properties[i].type) property.type = properties[i].type;
+                    if (properties[i].defaultValue) property.defaultValue = properties[i].defaultValue;
+                    this.addProperty(property);
+                    imports.Parser.Parser.addSymbol(property);
+                }
+            }
+            
+            // config..
+            var conf = this.comment.getTag("cfg");
+            if (conf.length) {
+                for (var i = 0; i < conf.length; i++) {
+                    this.addConfig(conf[i]);
+                }
+            }
+            
+            /*~t
+                // todo
+            */
+
+            // @return
+            var returns = this.comment.getTag("return");
+            if (returns.length) { // there can be many return tags in a single doclet
+                this.returns = returns;
+                this.type = returns.map(function($){return $.type}).join(", ");
+            }
+            
+            /*~t
+                // todo
+            */
+            
+            // @exception
+            this.exceptions = this.comment.getTag("throws");
+            
+            /*~t
+                // todo
+            */
+            
+            // @requires
+            var requires = this.comment.getTag("requires");
+            if (requires.length) {
+                this.requires = requires.map(function($){return $.desc});
+            }
+            
+            /*~t
+                // todo
+            */
+            
+            // @type
+            var types = this.comment.getTag("type");
+            if (types.length) {
+                this.type = types[0].desc; //multiple type tags are ignored
+            }
+            
+            /*~t
+                // todo
+            */
+            
+            // @private
+            if (this.comment.getTag("private").length || this.isInner) {
+                this.isPrivate = true;
+            }
+            
+            // @ignore
+            if (this.comment.getTag("ignore").length) {
+                this.isIgnored = true;
+            }
+            
+            /*~t
+                // todo
+            */
+            
+            // @inherits ... as ...
+            var inherits = this.comment.getTag("inherits");
+            if (inherits.length) {
+                for (var i = 0; i < inherits.length; i++) {
+                    if (/^\s*([a-z$0-9_.#-]+)(?:\s+as\s+([a-z$0-9_.#]+))?/i.test(inherits[i].desc)) {
+                        var inAlias = RegExp.$1;
+                        var inAs = RegExp.$2 || inAlias;
+
+                        if (inAlias) inAlias = inAlias.replace(/\.prototype\.?/g, "#");
+                        
+                        if (inAs) {
+                            inAs = inAs.replace(/\.prototype\.?/g, "#");
+                            inAs = inAs.replace(/^this\.?/, "#");
+                        }
+
+                        if (inAs.indexOf(inAlias) != 0) { //not a full namepath
+                            var joiner = ".";
+                            if (this.alias.charAt(this.alias.length-1) == "#" || inAs.charAt(0) == "#") {
+                                joiner = "";
+                            }
+                            inAs = this.alias + joiner + inAs;
+                        }
+                    }
+                    this.inherits.push({alias: inAlias, as: inAs});
+                }
+            }
+            
+            /*~t
+                // todo
+            */
+
+            // @augments
+            this.augments = this.comment.getTag("augments");
+            
+            //@extends - Ext
+            if (this.comment.getTag("extends")) {   
+                this.augments = this.comment.getTag("extends");
+            }
+            
+            
+            // @default
+            var defaults = this.comment.getTag("default");
+            if (defaults.length) {
+                if (this.is("OBJECT")) {
+                    this.defaultValue = defaults[0].desc;
+                }
+            }
+            
+            /*~t
+                // todo
+            */
+            
+            // @memberOf
+            var memberOfs = this.comment.getTag("memberOf");
+            if (memberOfs.length) {
+                this.memberOf = memberOfs[0].desc;
+                this.memberOf = this.memberOf.replace(/\.prototype\.?/g, "#");
+                this.name = this.name.split('.').pop();
+                this.name = this.name.split('#').pop();
+                this.name = this.memberOf + this.name;
+                this._name = this.name
+                this.alias = this.name;
+            }
+
+            /*~t
+                // todo
+            */
+            
+            // @public
+            if (this.comment.getTag("public").length) {
+                this.isPrivate = false;
+            }
+            
+            /*~t
+                // todo
+            */
+        },
+
+        is : function(what) {
+            return this.isa === what;
+        },
+
+        isBuiltin : function() {
+            return SymbolSet.isBuiltin(this.alias);
+        },
+
+        setType : function(/**String*/comment, /**Boolean*/overwrite) {
+            if (!overwrite && this.type) return;
+            var typeComment = DocComment.unwrapComment(comment);
+            this.type = typeComment;
+        },
+
+        inherit : function(symbol) {
+            if (!this.hasMember(symbol.name) && !symbol.isInner) {
+                if (symbol.is("FUNCTION"))
+                    this.methods.push(symbol);
+                else if (symbol.is("OBJECT"))
+                    this.properties.push(symbol);
+            }
+        },
+
+        hasMember : function(name) {
+            return (this.hasMethod(name) || this.hasProperty(name));
+        },
+
+        addMember : function(symbol) {
+            //println("ADDMEMBER: " + this.name +  " ++ " + symbol.name);
+            
+            if (symbol.comment.getTag("cfg").length == 1) { 
+                symbol.comment.getTag("cfg")[0].memberOf = this.alias;
+                this.addConfig(symbol.comment.getTag("cfg")[0]);
+                return;
+            }
+            
+            if (symbol.is("FUNCTION")) { this.addMethod(symbol); }
+            else if (symbol.is("OBJECT")) { this.addProperty(symbol); }
+        },
+
+        hasMethod : function(name) {
+            var thisMethods = this.methods;
+            for (var i = 0, l = thisMethods.length; i < l; i++) {
+                if (thisMethods[i].name == name) return true;
+                if (thisMethods[i].alias == name) return true;
+            }
+            return false;
+        },
+
+        addMethod : function(symbol) {
+            var methodAlias = symbol.alias;
+            var thisMethods = this.methods;
+            for (var i = 0, l = thisMethods.length; i < l; i++) {
+                if (thisMethods[i].alias == methodAlias) {
+                    thisMethods[i] = symbol; // overwriting previous method
+                    return;
+                }
+            }
+            thisMethods.push(symbol); // new method with this alias
+        },
+
+        hasProperty : function(name) {
+            var thisProperties = this.properties;
+            for (var i = 0, l = thisProperties.length; i < l; i++) {
+                if (thisProperties[i].name == name) return true;
+                if (thisProperties[i].alias == name) return true;
+            }
+            return false;
+        },
+
+        addProperty : function(symbol) {
+            var propertyAlias = symbol.alias;
+            var thisProperties = this.properties;
+            for (var i = 0, l = thisProperties.length; i < l; i++) {
+                if (thisProperties[i].alias == propertyAlias) {
+                    thisProperties[i] = symbol; // overwriting previous property
+                    return;
+                }
+            }
+
+            thisProperties.push(symbol); // new property with this alias
+        },
+        
+        addDocTag : function(docTag)
+        {
+            this.comment.tags.push(docTag);
+            if (docTag.title == 'cfg') {
+                this.addConfig(docTag);
+            }
+            
+        },
+        
+        addConfig : function(docTag)
+        {
+            if (typeof(docTag['memberOf']) == 'undefined') {
+                // remove prototype data...
+                //var a = this.alias.split('#')[0];
+                //docTag.memberOf = a;
+                docTag.memberOf = this.alias;
+            }
+            if (typeof(this.cfgs[docTag.name]) == 'undefined') {
+                this.cfgs[docTag.name] = docTag;
+            }
+            
+        },
+        configToArray: function()
+        {
+            var r = [];
+            for(var ci in this.cfgs) {
+                // dont show hidden!!
+                if (this.cfgs[ci].desc.match(/@hide/)) {
+                    continue;
+                }
+                r.push(this.cfgs[ci]); 
+               
+            }
+            return r;
+        }
+});
+
+/**
+ * Elements that are not serialized
+ * 
+ */
+Symbol.hide = [ 
+    '$args' // not needed AFAIK
+]
+
+Symbol.srcFile = ""; //running reference to the current file being parsed
+
+
+Symbol.fromDump = function(t)
+{
+    var ns = new Symbol();
+    for (var i in t) {
+        if (typeof(ns[i]) == "undefined") {
+            println("ERR:no default for Symbol:"+ i);
+        }
+        ns[i] = t[i];
+    }
+    return ns;
+}
diff --git a/JSDOC/SymbolSet.js b/JSDOC/SymbolSet.js
new file mode 100644 (file)
index 0000000..5843a94
--- /dev/null
@@ -0,0 +1,338 @@
+//<script type="text/javascript">
+
+XObject         = imports.XObject.XObject;
+DocComment      = imports.DocComment.DocComment;
+// circular references..
+///Options         = imports.BuildDocs.Options;
+//Parser          = imports.Parser.Parser;
+//Symbol          = imports.Symbol.Symbol;
+
+
+
+SymbolSet = XObject.define(
+    function() {
+        this.init();
+    },
+    Object,
+    {
+        
+        _index : false,
+        
+        
+        init : function() {
+            this._index = {};
+        },
+
+        keys : function() 
+        {
+            var found = [];
+            for (var p in this._index) {
+                found.push(p);
+            }
+            return found;
+        },
+
+
+        hasSymbol : function(alias) {
+            return typeof(this._index[alias]) != 'undefined';
+            //return this.keys().indexOf(alias) > -1;
+        },
+
+        addSymbol : function(symbol) {
+            //print("ADDING SYMBOL:"+symbol.alias.toString());
+            
+            
+            if (this.hasSymbol(symbol.alias)) {
+                imports.BuildDocs.Options.LOG.warn("Overwriting symbol documentation for: "+symbol.alias + ".");
+            }
+            this._index[symbol.alias] = symbol;
+        },
+
+        getSymbol : function(alias) {
+            
+            if (this.hasSymbol(alias)) return this._index[alias];
+            return false;
+        },
+
+        toArray : function() {
+            var found = [];
+            for (var p in this._index) {
+                found.push(this._index[p]);
+            }
+            return found;
+        },
+        /**
+         * for serializing
+         */
+        toJSON : function() {
+            return {
+                '*object' : 'SymbolSet',
+                _index : this._index
+            };
+            
+        },
+
+
+        deleteSymbol : function(alias) {
+            if (!this.hasSymbol(alias)) return;
+            delete this._index[alias];
+        },
+
+        renameSymbol : function(oldName, newName) {
+            // todo: should check if oldname or newname already exist
+            if (typeof(this._index[oldName]) == "undefined") {
+                throw "Cant rename " + oldName + " to " + newName + " As it doesnt exist";
+               }
+            this._index[newName] = this._index[oldName];
+            this.deleteSymbol(oldName);
+            this._index[newName].alias = newName;
+            return newName;
+        },
+
+        relate : function() {
+            this.resolveBorrows();
+            this.resolveMemberOf();
+            this.resolveAugments();
+        },
+
+        resolveBorrows : function() {
+            for (p in this._index) {
+                var symbol = this._index[p];
+                
+                
+                
+                if (symbol.is("FILE") || symbol.is("GLOBAL")) continue;
+                
+                var borrows = symbol.inherits;
+                for (var i = 0; i < borrows.length; i++) {
+                    var borrowed = this.getSymbol(borrows[i].alias);
+                    if (!borrowed) {
+                        imports.BuildDocs.Options.LOG.warn("Can't borrow undocumented "+borrows[i].alias+".");
+                        continue;
+                    }
+                    
+                    var borrowAsName = borrows[i].as;
+                    var borrowAsAlias = borrowAsName;
+                    if (!borrowAsName) {
+                        imports.BuildDocs.Options.LOG.warn("Malformed @borrow, 'as' is required.");
+                        continue;
+                    }
+                    
+                    if (borrowAsName.length > symbol.alias.length && borrowAsName.indexOf(symbol.alias) == 0) {
+                        borrowAsName = borrowAsName.replace(borrowed.alias, "")
+                    }
+                    else {
+                        var joiner = "";
+                        if (borrowAsName.charAt(0) != "#") joiner = ".";
+                        borrowAsAlias = borrowed.alias + joiner + borrowAsName;
+                    }
+                    
+                    borrowAsName = borrowAsName.replace(/^[#.]/, "");
+                            
+                    if (this.hasSymbol(borrowAsAlias)) continue;
+
+                    var clone = borrowed.clone();
+                    clone.name = borrowAsName;
+                    clone.alias = borrowAsAlias;
+                    this.addSymbol(clone);
+                }
+            }
+        },
+
+        resolveMemberOf : function() {
+            for (var p in this._index) {
+                var symbol = this.getSymbol(p);
+                
+                if (symbol.is("FILE") || symbol.is("GLOBAL")) continue;
+                
+                // the memberOf value was provided in the @memberOf tag
+                else if (symbol.memberOf) {
+                    var parts = symbol.alias.match(new RegExp("^("+symbol.memberOf+"[.#-])(.+)$"));
+                    
+                    // like foo.bar is a memberOf foo
+                    if (parts) {
+                        symbol.memberOf = parts[1];
+                        symbol.name = parts[2];
+                    }
+                    // like bar is a memberOf foo
+                    else {
+                        var joiner = symbol.memberOf.charAt(symbol.memberOf.length-1);
+                        if (!/[.#-]/.test(joiner)) symbol.memberOf += ".";
+                        
+                        this.renameSymbol(p, symbol.memberOf + symbol.name);
+                    }
+                }
+                // the memberOf must be calculated
+                else {
+                    var parts = symbol.alias.match(/^(.*[.#-])([^.#-]+)$/);
+                    if (parts) {
+                        symbol.memberOf = parts[1];
+                        symbol.name = parts[2];                                
+                    }
+                }
+
+                // set isStatic, isInner
+                if (symbol.memberOf) {
+                    switch (symbol.memberOf.charAt(symbol.memberOf.length-1)) {
+                        case '#' :
+                            symbol.isStatic = false;
+                            symbol.isInner = false;
+                            break;
+                            
+                        case '.' :
+                            symbol.isStatic = true;
+                            symbol.isInner = false;
+                            break;
+                            
+                        case '-' :
+                            symbol.isStatic = false;
+                            symbol.isInner = true;
+                            break;
+                            
+                    }
+                }
+                
+                // unowned methods and fields belong to the global object
+                if (!symbol.is("CONSTRUCTOR") && !symbol.isNamespace && symbol.memberOf == "") {
+                    symbol.memberOf = "_global_";
+                }
+                
+                // clean up
+                if (symbol.memberOf.match(/[.#-]$/)) {
+                    symbol.memberOf = symbol.memberOf.substr(0, symbol.memberOf.length-1);
+                }
+                //print("looking for memberOf: " + symbol.memberOf + " FOR " + symbol.alias);
+                // add to parent's methods or properties list
+                if (symbol.memberOf) {
+                    var container = this.getSymbol(symbol.memberOf);
+                    if (!container) {
+                        if (SymbolSet.isBuiltin(symbol.memberOf)) {
+                            container = imports.Parser.Parser.addBuiltin(symbol.memberOf);
+                        }
+                        else {
+                           // print("symbol NOT a BUILT IN - createing a container");
+                            // Eg. Ext.y.z (missing y)
+                            // we need to add in the missing symbol...
+                            container = new imports.Symbol.Symbol(symbol.memberOf, [], "OBJECT", new DocComment(""));
+                            container.isNamespace = true;
+                            this.addSymbol( container );
+                           // print(container.toSource());
+                            //container = this.getSymbol(symbol.memberOf);
+                            // fake container ... so dont ad symbols to it..
+                            continue;
+                            container = false;
+                            //LOG.warn("Can't document "+symbol.name +" as a member of undocumented symbol "+symbol.memberOf+".");
+                            //LOG.warn("We only have the following symbols: \n" + 
+                            //    this.keys.toSource());
+                        }
+                    }
+                    
+                    if (container && !container.isNamespace) container.addMember(symbol);
+                }
+            }
+        },
+
+        resolveAugments : function() {
+            // does this sort out multiple extends???
+            for (var p in this._index) {
+                var symbol = this.getSymbol(p);
+                this.buildAugmentsList(symbol); /// build heirachy of inheritance...
+                if (symbol.alias == "_global_" || symbol.is("FILE")) continue;
+                
+                var augments = symbol.augments;
+                for(var ii = 0, il = augments.length; ii < il; ii++) {
+                    var contributer = this.getSymbol(augments[ii]);
+                    
+                    
+                    
+                    if (contributer) {
+                        contributer.childClasses.push(symbol.alias);
+                        symbol.inheritsFrom.push(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.");
+                        //}
+                        //else {
+                            var cmethods = contributer.methods;
+                            var cproperties = contributer.properties;
+                            var cfgs = contributer.cfgs;
+                            for (var ci = 0, cl = cmethods.length; ci < cl; ci++) {   
+                                symbol.inherit(cmethods[ci]);
+                            }
+                            for (var ci = 0, cl = cproperties.length; ci < cl; ci++) {
+                                symbol.inherit(cproperties[ci]);
+                            }
+                            for (var ci in cfgs) {
+                                symbol.addConfig(cfgs[ci]);
+                            }
+                            
+                                
+                        //}
+                    }
+                    else {
+                        
+                        imports.BuildDocs.Options.LOG.warn("Can't augment contributer: '"+augments[ii]+"', not found. FOR: " + symbol.alias);
+                        
+                        //LOG.warn("We only have the following symbols: \n" + 
+                          //      this.keys().toSource().split(",").join(",    \n"));
+                       }
+
+                }
+            }
+        },
+
+        buildAugmentsList : function(symbol)
+        {
+            // basic idea is to add all the child extends to the parent.. without looping forever..
+            
+            if (!symbol.augments.length) {
+                return;
+            }
+            
+            var _t = this;
+            print("buildAugmentsList:" + symbol.alias);
+            var addAugments = function (alist, forceit) { // returns number added..
+                if (!alist.length) {
+                    return 0;
+                }
+                print("buildAugmentsList:addAugments" + alist.length);
+                var rval = 0;
+                for(var ii = 0; ii < alist.length; ii++) {
+                    print("getAlias:" + alist[ii]);
+                    if (alist[ii] == symbol.alias) {
+                        continue;
+                    }
+                    var contributer = _t.getSymbol(alist[ii]);
+                    if (!contributer) {
+                        continue;
+                    }
+                    
+                    if (!forceit && symbol.augments.indexOf(alist[ii]) > -1) {
+                        continue;
+                    }
+                    if (symbol.augments.indexOf(alist[ii]) < 0) {
+                        symbol.augments.push(alist[ii]);
+                    }
+                        
+                    
+                    addAugments(contributer.augments,false);
+                    
+                    rval++;
+                }
+                print("buildAugmentsList: ADDED:" + rval);
+                return rval;
+            }
+            addAugments(symbol.augments, true);
+            //while(addAugments(symbol.augments) >  0) { }
+            
+        }
+         
+})
+
+SymbolSet.isBuiltin = function(name) {
+    return (SymbolSet.isBuiltin.coreObjects.indexOf(name) > -1);
+}
+SymbolSet.isBuiltin .coreObjects = [
+    '_global_', 'Array', 'Boolean', 'Date', 'Function', 
+    'Math', 'Number', 'Object', 'RegExp', 'String'
+];
\ No newline at end of file
diff --git a/JSDOC/Template.js b/JSDOC/Template.js
deleted file mode 100644 (file)
index 4848199..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-//<script type="text/javscript">
-
-Gio = imports.gi.Gio;
-GLib = imports.gi.GLib;
-
-imports['Object.js'].load(Object);
-
-
-
-console = imports['console.js'].console;
-xnew    = imports['xnew.js'].xnew;
-Link    = imports['JSDOC/Template/Link.js'].Link;
-
-
-
-
-Template = function(templateFile) {
-       if (templateFile) {
-        
-        this.template = Gio.simple_read(templateFile);
-        
-    }
-       
-       this.templateFile = templateFile;
-    this.templateName = GLib.path_get_basename(templateFile);
-       this.code = "";
-       this.parse();
-}
-
-
-
-
-Object.extend(Template.prototype , {
-    
-
-    parse : function() {
-        
-        console.log("Parsing template? " + this.templateName);
-        
-        this.template = this.template.replace(/\{#[\s\S]+?#\}/gi, "");
-        this.code = "var output=``"+this.template;
-
-        this.code = this.code.replace(
-            /<for +each="(.+?)" +in="(.+?)" *>/gi, 
-            function (match, eachName, inName) {
-                return "``;\rvar $"+eachName+"_keys = keys("+inName+");\rfor(var $"+eachName+"_i = 0; $"+eachName+"_i < $"+eachName+"_keys.length; $"+eachName+"_i++) {\rvar $"+eachName+"_last = ($"+eachName+"_i == $"+eachName+"_keys.length-1);\rvar $"+eachName+"_key = $"+eachName+"_keys[$"+eachName+"_i];\rvar "+eachName+" = "+inName+"[$"+eachName+"_key];\routput+=``";
-            }
-        );     
-        this.code = this.code.replace(/<if test="(.+?)">/g, "``;\rif ($1) { \routput+=``");
-        this.code = this.code.replace(/<else\s*\/>/g, "``;} \relse\r{ \routput+=``");
-        
-        this.code = this.code.replace(/<\/(if|for)>/g, "``;\r};\routput+=``");
-        
-        //File.write("/tmp/jstookit_eval_"+this.templateName+".4.js", this.code);
-        
-        this.code = this.code.replace(
-            /\{\+\s*([\s\S]+?)\s*\+\}/gi,
-            function (match, code) {
-                code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
-                code = code.replace(/(\r?\n)/g, " ");
-                return "``+ \r("+code+") +\r``";
-            }
-        );
-        //File.write("/tmp/jstookit_eval_"+this.templateName+".6.js", this.code);
-        
-        this.code = this.code.replace(
-            /\{!\s*([\s\S]+?)\s*!\}/gi,
-            function (match, code) {
-                code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
-                code = code.replace(/(\n)/g, " "); // remove quotes..
-                return "``; "+code+";\routput+=``";
-            }
-        );
-       //File.write("/tmp/jstookit_eval_"+this.templateName+".7.js", this.code);
-        this.code = this.code+"``;";
-
-        
-        
-        this.code = this.code.replace(/(\r?\n)/g, "\\n");
-        this.code = this.code.replace(/"/g, "\\\"");
-        
-        this.code = this.code.replace(/``/g, "\"");
-        this.code = this.code.replace(/\\r/g, "\n");
-        //File.write("/tmp/jstookit_eval_"+this.templateName+".9.js", this.code);
-        this.code = this.code.replace(/\r/g, "\n\n");
-        
-
-    },
-
-    toCode : function() {
-        return this.code;
-    },
-
-    keys : function(obj) {
-        var keys = [];
-        if (obj && obj.constructor.toString().indexOf("Array") > -1) {
-            for (var i = 0; i < obj.length; i++) {
-                keys.push(i);
-            }
-        }
-        else {
-            for (var i in obj) {
-                keys.push(i);
-            }
-        }
-        return keys;
-    },
-
-    values : function(obj) {
-        var values = [];
-        if (obj.constructor.toString().indexOf("Array") > -1) {
-            for (var i = 0; i < obj.length; i++) {
-                values.push(obj[i]);
-            }
-        }
-        else {
-            for (var i in obj) {
-                values.push(obj[i]);
-            }
-        }
-        
-        
-        return values;
-    },
-
-    process : function(data) {
-        
-        //console.log("processing template");
-        var keys = this.keys;
-        var values = this.values;
-        
-        var makeSortby = this.makeSortby;
-        var makeSignature = this.makeSignature;
-        var summarize = this.summarize ;
-        var makeFuncSkel = this.makeFuncSkel;
-        var resolveLinks = this.resolveLinks;
-        var makeImage = this.makeImage;
-        // usefull for cross refing..
-        Template.data = data;
-        
-        
-        
-        try {
-             eval(this.code);
-           } catch (e) {
-             Gio.simple_write('/tmp/template.js', this.code);
-             Seed.print('in /tmp/template.js');
-            throw e;
-            Seed.quit();
-            }
-        
-        
-        //File.write("/tmp/jstookit_eval.js", this.code);
-        //try {
-        //eval('include     "/tmp/jstookit_eval.js";');
-        //includeJs("/tmp/jstookit_eval.js");
-            //eval(this.code);
-       // console.log("done eval of template");   
-        
-        return output;
-    },
-
-    isdefined : function (typ) {
-        return typ != 'undefined';
-    },
-    
-    
-    summarize : function(desc) {
-        if (typeof desc != "undefined")
-            return desc.match(/([\w\W]+?\.)[^a-z0-9]/i)? RegExp.$1 : desc;
-    },
-
-    /** make a symbol sorter by some attribute */
-    makeSortby : function(attribute) {
-        return function(a, b) {
-            if (a[attribute] != undefined && b[attribute] != undefined) {
-                a = a[attribute]; //.toLowerCase();
-                b = b[attribute];//.toLowerCase();
-                if (a < b) return -1;
-                if (a > b) return 1;
-                return 0;
-            }
-        }
-    },
-    makeImage : function(alias) {
-        ///  http://library.gnome.org/devel/gtk/stable/notebook.png
-        var ns = alias.split('.').shift();
-        var cls = alias.split('.').pop().toLowerCase();
-        if (ns != 'Gtk' ) {
-            return '';//ns;
-        }
-        return '<img class="class-picture" src="http://library.gnome.org/devel/gtk/stable/' + cls + '.png">';
-        
-        
-    },
-    
-    
-
-    makeSignature : function(params) {
-        if (!params) return "()";
-        var signature = "("    +
-            params.filter(
-                function($) {
-                    return $.name.indexOf(".") == -1; // don't show config params in signature
-                }
-            ).map(
-                function($) {
-                    $.defaultValue = typeof($.defaultValue) == 'undefined' ? false : $.defaultValue;
-                    
-                    return "" +
-                        ($.isOptional ? "[" : "") +
-                        (($.type) ? 
-                            (new Link().toSymbol(
-                                (typeof($.type) == 'object' ) ? 'Function' : $.type
-                            )) + " " :  ""
-                        )   + 
-                        "<B><i>" +$.name + "</i></B>" +
-                        ($.defaultValue ? "=" +item.defaultValue : "") +
-                        ($.isOptional ? "]" : "");
-                    
-                     
-                }
-            ).join(", ")
-        +
-        ")";
-        return signature;
-    },
-
-    makeFuncSkel :  function(params) {
-        if (!params) 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}";
-        
-    },
-
-    /** Find symbol {@link ...} strings in text and turn into html links */
-    resolveLinks : function (str, from) {
-        if (!str || typeof(str) == 'undefined') {
-            return '';
-        }
-        
-        // gtk specific. now..
-        // @ -> bold.. - they are arguments..
-        
-        str = str.replace(/@([a-z_]+)/gi,
-            function(match, symbolName) {
-                return '<b>' + symbolName + '</b>';
-            }
-        );
-        // constants.
-        str = str.replace(/%([a-z_]+)/gi,
-            function(match, symbolName) {
-                return '<b>' + symbolName + '</b>';
-            }
-        );
-        
-        str = str.replace(/#([a-z_]+)/gi,
-            function(match, symbolName) {
-                return '<b>' + symbolName + '</b>';
-                // this should do a lookup!!!!
-                /// it could use data in the signature to find out..
-                //return new Link().toSymbol(Template.data.ns + '.' + symbolName);
-            }
-        );
-        
-        str = str.replace(/\n/gi, '<br/>');
-        
-        /*
-        str = str.replace(/\{@link ([^} ]+) ?\}/gi,
-            function(match, symbolName) {
-                return new Link().toSymbol(symbolName);
-            }
-        );
-        */
-        /*
-        str = str.replace(/\{([a-z\.\/]+)\}/gi,
-            function(match, symbolName) {
-                //println("got match " + symbolName);
-                bits = symbolName.split('/');
-                var mret = '';
-                for(var i = 0; i < bits.length; i++) {
-                    
-                    mret += (mret.length ? '&nbsp;|&nbsp;' : '') + new Link().toSymbol(bits[i]);
-                }
-                
-                return mret; //new Link().toSymbol(symbolName);
-            }
-        );
-        */
-        // look for aaaa.\S+  ??? this might work???
-        /*
-        str = str.replace(/\([a-z]+\.\S+)/gi,
-            function(match, symbolName) {
-                return new Link().toSymbol(symbolName);
-            }
-        );
-        */
-        
-        return str;
-    }
-    
-    
-});
\ No newline at end of file
diff --git a/JSDOC/Template/Link.js b/JSDOC/Template/Link.js
deleted file mode 100644 (file)
index a550e49..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-//<script type="text/javascript">
-
-console = imports['console.js'].console;
-
-imports['Object.js'].load(Object);
-
-Template = imports['JSDOC/Template.js'];
-
-/** Handle the creation of HTML links to documented symbols.
-       @constructor
-    * 
-    * // JSDOC.Template.Link.base = "";
-    * JSDOC.Template.Link.symbolsDir
-    * 
-*/
-
-Link = function() {
-       this.alias = "";
-       this.src = "";
-       this.file = "";
-       this.text = "";
-       this.innerName = "";
-       this.classLink = false;
-       this.targetName = "";
-    
-    Link.symbolsDir = Link.symbolsDir || '';
-    Link.base = Link.base || '';
-    Link.ext= Link.ext || '';
-    Link.srcDir= Link.srcDir || '';
-        
-    
-}
-
-
-
-Object.extend(Link.prototype, {
-    
-    alias : "",
-       src : "",
-       file : "",
-       text : "",
-       innerName : "",
-       classLink : false,
-       targetName : "",
-    
-    
-    
-    toString : function() {
-               var linkString;
-               var thisLink = this;
-        
-        if (this.none) {
-            return 'none';
-        }
-               if (this.alias) {
-            
-            if (typeof(this.builtins[this.alias]) != 'undefined') {
-                this.text = this.alias;
-                return thisLink._makeExternLink(this.builtins[this.alias]);
-            }
-            
-            
-            return thisLink._makeSymbolLink(this.alias);
-            
-            /*
-            
-                       linkString = this.alias.replace(/(^|[^a-z$0-9_#.:-])([|a-z$0-9_#.:-]+)($|[^a-z$0-9_#.:-])/i,
-                               function(match, prematch, symbolName, postmatch) {
-                                       var symbolNames = symbolName.split("|");
-                                       var links = [];
-                                       for (var i = 0, l = symbolNames.length; i < l; i++) {
-                                               thisLink.alias = symbolNames[i];
-                                               links.push(thisLink._makeSymbolLink(symbolNames[i]));
-                                       }
-                                       return prematch+links.join("|")+postmatch;
-                               }
-                       );
-            */
-               }
-               else if (this.extern) {
-                       linkString = thisLink._makeExternLink(this.extern);
-               }
-               else if (this.src) {
-                       linkString = thisLink._makeSrcLink(this.src);
-               }
-               else if (this.file) {
-                       linkString = thisLink._makeFileLink(this.file);
-               }
-
-               return linkString;
-       },
-    
-    builtins : {
-        'Object' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Object',
-        //'Object...' : 'http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object',
-        'Array' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array',
-        'Function' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Function',
-        'String' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/String',
-        'Number' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Number',
-        'Boolean' : 'https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Boolean',
-        'HTMLElement' : 'http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037'
-    },
-    
-    
-    toGnome: function(alias) 
-    {
-        this.file = "#";
-        var pr = alias.split('.');
-        var aa = alias;
-        var site = 'library.gnome.org';
-        var extra = '';
-        switch(pr[0]) {
-            case 'GIRepository':
-               this.extern = 'http://live.gnome.org/GObjectIntrospection';
-               aa = pr[0];
-               break;
-            case 'Gio':   
-            case 'GLib':   
-            case 'GObject':   
-                aa = pr.length > 1 ? 'G' + pr[1] : pr[0];
-                break;
-            case 'GdkPixbuf':   
-                aa = pr.length > 1 ? 'Gdk' + pr[1] : pr[0];
-                break;
-            case 'GtkSource':   
-                aa = pr.length > 1 ? pr[0] + pr[1] : 'GtkSourceView';
-                break;
-                
-            case 'Gst': 
-                aa = pr.length > 1 ? pr[0] + pr[1] : 'GStreamer';
-                break;
-            
-            case 'Pango':
-                extra = ' GTK-Doc';
-                break;
-            case 'GstController': 
-            case 'GstApp': 
-            case 'GstAudio': 
-            case 'GstBase': 
-            case 'GstCheck': 
-            case 'GstFft': 
-            case 'GstInterfaces': 
-            case 'GstNet': 
-            case 'GstNetbuffer': 
-            case 'GstPbutils': 
-            case 'GstRiff': 
-            case 'GstRtp': 
-            case 'GstRtsp': 
-            case 'GstSdp': 
-            case 'GstTag': 
-            case 'GstVideo': 
-            
-                aa = pr.length > 1 ? 'Gst' + pr[1] : pr[0];
-                break;
-                
-            case 'Epiphany':     
-                aa = pr.length > 1 ?  pr[1] : pr[0];
-                break;
-            case 'WebKit':
-                site = 'webkitgtk.org';
-            
-            default:
-                
-                aa = alias.replace('.', '');
-                
-                break;
-         
-        }
-        if (!this.extern) {
-            this.extern = 'http://www.google.com/search?hl=en&amp;' + 
-                    'q=site%3A' + site  + '+' + aa + extra +
-                    '&amp;btnI=I%27m+Feeling+Lucky&amp;meta=&amp;aq=f&amp;oq=';
-        }
-        
-        this.text =  aa;
-        return this;
-    },
-    
-       target : function(targetName) {
-               if (typeof(targetName) != 'undefined') this.targetName = targetName;
-               return this;
-       },
-       inner : function(inner) {
-               if (typeof(inner) != 'undefined') this.innerName = inner;
-               return this;
-       },
-       withText:  function(text) {
-               if (typeof(text) != 'undefined') this.text = text;
-               return this;
-       },
-       toSrc :function(filename) {
-               if (typeof(filename) != 'undefined') this.src = filename;
-               return this;
-       },
-    
-    toSymbolLong : function(alias)
-    {
-        this.show_full = true;
-        return this.toSymbol(alias)
-    },
-       toSymbol : function(alias) {
-        
-        
-        switch(alias) {
-            case 'boolean' : this.alias = 'Boolean'; return this;
-            case 'int' : this.alias = 'Number'; return this;
-            case 'uint' : this.alias = 'Number'; return this;
-            
-            case 'long' : this.alias = 'Number'; return this;
-            case 'ulong' : this.alias = 'Number'; return this;
-            
-            
-            case 'uint8' : this.alias = 'Number'; return this;
-            case 'int8' : this.alias = 'Number'; return this;
-            
-            case 'uint16' : this.alias = 'Number'; return this;
-            case 'uint16' : this.alias = 'Number'; return this;
-            
-            case 'int32' : this.alias = 'Number'; return this;
-            case 'uint32' : this.alias = 'Number'; return this;
-            
-            case 'uint64' : this.alias = 'Number'; return this;
-            case 'int64' : this.alias = 'Number'; return this;
-            
-            
-            case 'GType' : this.alias = 'Number'; return this;
-            case 'size' : this.alias = 'Number'; return this;
-            case 'ssize' : this.alias = 'Number'; return this;
-            
-            case 'float' : this.alias = 'Number'; return this;
-            case 'double' : this.alias = 'Number'; return this;
-            case 'time_t' : this.alias = 'Number'; return this;
-            // fixme - should find out more details..
-            case 'array' : this.alias = 'Array'; return this;
-            case 'gslist' : this.alias = 'Array'; return this;
-            case 'glist' : this.alias = 'Array'; return this; // homefully.
-            case 'ghash' : this.alias = 'Object'; return this; // homefully.
-            
-            
-            case 'error' : this.alias = 'Object'; return this; // homefully.
-            case 'filename' : this.alias = 'String'; return this; // hopefully..
-            case 'utf8' : this.alias = 'String'; return this;
-            
-            case 'void' : this.none = true; return this;
-            
-            
-        }
-        
-        
-               if (typeof(alias) != 'undefined') {
-            this.alias = new String(alias);
-        }
-               return this;
-       },
-       toClass : function(alias) {
-               this.classLink = true;
-               return this.toSymbol(alias);
-       },
-       toFile : function(file) {
-               if (typeof(file) != 'undefined') this.file = file;
-               return this;
-       },
-       
-       
-  
-
-    /** prefixed for hashes */
-
-
-    /** Appended to the front of relative link paths. */
-
-
-    symbolNameToLinkName : function(symbol) {
-        var linker = "";
-        if (symbol.isStatic) linker = ".";
-        else if (symbol.isInner) linker = "-";
-        
-        return linker+symbol.name;
-    },
-
-    
-
-
-    /** Create a link to a snother symbol. */
-    _makeSymbolLink :  function(alias) 
-    {
-        var target = '';
-        var txt = this.show_full ? alias : alias.split('.').pop();
-         return "<a href=\"./"+alias+".html\""+target+">"+txt+"</a>";    
-        
-        /*
-        // look for '/' in alias..
-        if (/\//.test(alias)) {
-            var bits = alias.split('/');
-            var ret = "";
-            for(var i=0; i < bits.length; i++) {
-                if (i > 0) {
-                    ret +="/";
-                }
-                ret += this._makeSymbolLink(bits[i]);
-            }
-            return ret;
-            
-        }
-        
-        
-        */
-        
-        var linkBase = Link.base + Link.symbolsDir;
-        //var linkTo = Link.symbolSet.getSymbol(alias);
-        linkTo = "FIXME";
-        var linkPath;
-        var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
-        
-        // is it an internal link?
-        if (alias.charAt(0) == "#") {
-            linkPath = alias;
-            fullLinkPath = alias;
-        
-        // if there is no symbol by that name just return the name unaltered
-        } else if (!linkTo) {
-            
-            if (typeof(this.builtins[alias]) != 'undefined') {
-                return "<a href=\""+ this.builtins[alias]+"\""+target+">"+alias+"</a>";
-             }
-            
-            return this.text || alias;
-        
-        
-        // it's a symbol in another file
-        } else {
-
-            if (!linkTo.isConstructor && !linkTo.isNamespace) { // it's a method or property
-                linkPath = escape(linkTo.memberOf) || "_global_";
-                linkPath += Link.ext + "#" + this.symbolNameToLinkName(linkTo);
-            }
-            else {
-                linkPath = escape(linkTo.alias);
-                linkPath += Link.ext + (this.classLink? "":"#" +  "constructor");
-            }
-            //linkPath = linkBase + linkPath;
-            fullLinkPath = linkBase + linkPath;
-        }
-        
-        var linkText = this.text || alias;
-        
-        var link = {linkPath: linkPath, linkText: linkText, fullLinkPath: fullLinkPath};
-        
-        //if (typeof PluginManager != "undefined") {
-        //    JSDOC.PluginManager.run("onSymbolLink", link);
-        //}
-        
-        return "<a href=\""+link.fullLinkPath+"\""+target+">"+link.linkText+"</a>";
-    },
-
-
-    /** Create a link to a source file. */
-     _makeSrcLink : function(srcFilePath) {
-        var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
-            
-        // transform filepath into a filename
-        var srcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, "."); // was _
-        var lsrcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, ".");
-        var outFilePath = Link.base + Link.srcDir + srcFile.replace(/.js$/, '') + Link.ext;
-        
-        if (!this.text) this.text = FilePath.fileName(srcFilePath);
-        return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>";
-    },
-
-    /** Create a link to a source file. */
-     _makeFileLink : function(filePath) {
-        var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
-            
-        var outFilePath =  Link.base + filePath;
-
-        if (!this.text) this.text = filePath;
-        return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>";
-    },
-    
-    /** Create a link to a source file. */
-     _makeExternLink : function(filePath) {
-        var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
-            
-        if (!this.text) this.text = filePath;
-        return "<a href=\""+filePath+"\""+target+">"+this.text+"</a>";
-    }
-    
-});
\ No newline at end of file
index 007a982..a916386 100644 (file)
@@ -1,50 +1,49 @@
 //<script type="text/javscript">
 
+XObject = imports.XObject.XObject;
 
-imports['Object.js'].load(Object);
-
-JSDOC   = imports['JSDOC.js'].JSDOC;
 
 /**
        @constructor
 */
-TextStream = function(text) {
-       if (typeof(text) == "undefined") text = "";
-       text = ""+text;
-       this.text = text;
-       this.cursor = 0;
-}
-
-Object.extend( TextStream.prototype, { 
-    
-    look : function(n) {
-        if (typeof n == "undefined") n = 0;
-        
-        if (this.cursor+n < 0 || this.cursor+n >= this.text.length) {
-            var result = new String("");
-            result.eof = true;
-            return result;
-        }
-        return this.text.charAt(this.cursor+n);
+TextStream = XObject.define(
+    function(text) {
+        if (typeof(text) == "undefined") text = "";
+        text = ""+text;
+        this.text = text;
+        this.cursor = 0;
     },
-
-    next : function(n) {
-        if (typeof n == "undefined") n = 1;
-        if (n < 1) return null;
+    Object, 
+    { 
         
-        var pulled = "";
-        for (var i = 0; i < n; i++) {
-            if (this.cursor+i < this.text.length) {
-                pulled += this.text.charAt(this.cursor+i);
-            }
-            else {
+        look : function(n) {
+            if (typeof n == "undefined") n = 0;
+            
+            if (this.cursor+n < 0 || this.cursor+n >= this.text.length) {
                 var result = new String("");
                 result.eof = true;
                 return result;
             }
-        }
+            return this.text.charAt(this.cursor+n);
+        },
 
-        this.cursor += n;
-        return pulled;
-    }
+        next : function(n) {
+            if (typeof n == "undefined") n = 1;
+            if (n < 1) return null;
+            
+            var pulled = "";
+            for (var i = 0; i < n; i++) {
+                if (this.cursor+i < this.text.length) {
+                    pulled += this.text.charAt(this.cursor+i);
+                }
+                else {
+                    var result = new String("");
+                    result.eof = true;
+                    return result;
+                }
+            }
+
+            this.cursor += n;
+            return pulled;
+        }
 });
\ No newline at end of file
index 0486c68..465d70e 100644 (file)
@@ -1,14 +1,15 @@
 //<Script type="text/javascript">
 
-imports['Object.js'].load(Object);
-JSDOC   = imports['JSDOC.js'].JSDOC;
-console = imports['console.js'].console;
+XObject = imports.XObject.XObject;
+console = imports.console.console;
 /**
  *     @class Token
  * 
  *  @prop data {String} raw value of token
  *  @prop type {String} type of token
  *     TOKN  (unknown)          - name is UNKNOWN_TOKEN
+ * 
  *     KEYW  (keyword)          - name is upper case version of keyword
  *     NAME  (name/identifier)  - name is NAME
  *     COMM  (comment)          - name is MULTI_LINE_COMM, JSDOC, SINGLE_LINE_COMM
@@ -18,11 +19,21 @@ console = imports['console.js'].console;
  *     NUMB  (number)           - name is OCTAL,DECIMAL,HEC_DEC
  *     REGX   (reg.expression)  - name is REGX
  *  @prop name {String} see type details above
- *  @prop indentifier {Identifier} identifier class if relivant
+ *  @prop identifier {Identifier} identifier class if relivant
+ * 
+ * 
+ * 
+ * old mappings:
+ * 
+ * Script.TOKidentifier  - type == 'NAME'
+ * Script.TOKassign  = data == '='
+ * Script.TOKsemicolon data == '';
+ * 
+ * 
  * 
 */
 
-Token = Object.define(
+Token = XObject.define(
     function(data, type, name, line) {
         this.data = data;
         this.type = type;
@@ -31,12 +42,15 @@ Token = Object.define(
         this.prefix = '';    
         this.outData = false; // used by packer/scopeparser
         this.identifier = false; // used by scope
+        this.id = Token.id++;
     }, 
     Object, 
     {
          toString: function()
         {
-            return 'line:' + this.line + ', type:' + this.type + ', name:' + this.name + ', data:' + this.data;
+            return 'line:' + this.line + ', type:' + this.type + 
+                ', name:' + this.name + ', data:' + this.data + 
+                ((this.outData === false) ? '' : ( 'outData : ' + this.outData));
         },
         
         
@@ -92,4 +106,4 @@ Token = Object.define(
             return this.name === what || this.type === what;
         }
 });
-     
\ No newline at end of file
+Token.id = 0;     
\ No newline at end of file
index 4d795cf..e367849 100644 (file)
@@ -1,12 +1,12 @@
 //<script type="text/javascript">
 
-//imports['Object.js'].load(Object);
 XObject = imports.XObject.XObject;
-console = imports['console.js'].console;
+console = imports.console.console;
 
-JSDOC   = imports['JSDOC.js'].JSDOC;
-Token   = imports['JSDOC/Token.js'].Token;
-Lang    = imports['JSDOC/Lang.js'].Lang;
+
+Token   = imports.Token.Token;
+Lang    = imports.Lang.Lang;
 
 /**
        @class Search a {@link JSDOC.TextStream} for language tokens.
@@ -23,11 +23,18 @@ TokenReader = XObject.define(
     },
     Object,
     {
-            
+        collapseWhite : false, // only reduces white space...
 
         /**
-            @type {JSDOC.Token[]}
+         * tokenize a stream
+         * @return {Array} of tokens
+         * 
+         * ts = new TextStream(File.read(str));
+         * tr = TokenReader({ keepComments : true, keepWhite : true });
+         * tr.tokenize(ts)
+         * 
          */
+            
 
 
         tokenize : function(/**JSDOC.TextStream*/stream) {
@@ -85,12 +92,13 @@ TokenReader = XObject.define(
                 }
                 var n = found.split('.');
                 var p = false;
+                var _this = this;
                 n.forEach(function(nm) {
                     if (p) {
-                        tokens.push(new Token('.', "PUNC", "DOT", this.line));
+                        tokens.push(new Token('.', "PUNC", "DOT", _this.line));
                     }
                     p=true;
-                    tokens.push(new Token(nm, "NAME", "NAME", this.line));
+                    tokens.push(new Token(nm, "NAME", "NAME", _this.line));
                 });
                 return true;
                 
@@ -122,18 +130,18 @@ TokenReader = XObject.define(
         read_space : function(/**JSDOC.TokenStream*/stream, tokens) {
             var found = "";
             
-            while (!stream.look().eof && Lang.isSpace(stream.look())) {
+            while (!stream.look().eof && Lang.isSpace(stream.look()) && !Lang.isNewline(stream.look())) {
                 found += stream.next();
             }
             
             if (found === "") {
                 return false;
             }
-            else {
-                if (this.collapseWhite) found = " ";
-                if (this.keepWhite) tokens.push(new Token(found, "WHIT", "SPACE", this.line));
-                return true;
-            }
+            //print("WHITE = " + JSON.stringify(found)); 
+            if (this.collapseWhite) found = " ";
+            if (this.keepWhite) tokens.push(new Token(found, "WHIT", "SPACE", this.line));
+            return true;
+        
         },
 
         /**
@@ -141,7 +149,7 @@ TokenReader = XObject.define(
          */
         read_newline : function(/**JSDOC.TokenStream*/stream, tokens) {
             var found = "";
-            
+            var line = this.line;
             while (!stream.look().eof && Lang.isNewline(stream.look())) {
                 this.line++;
                 found += stream.next();
@@ -150,11 +158,19 @@ TokenReader = XObject.define(
             if (found === "") {
                 return false;
             }
-            else {
-                if (this.collapseWhite) found = "\n";
-                if (this.keepWhite) tokens.push(new Token(found, "WHIT", "NEWLINE", this.line));
-                return true;
+            //this.line++;
+            if (this.collapseWhite) {
+                found = "\n";
+            }
+            if (this.keepWhite) {
+                var last = tokens.pop();
+                if (last && last.name != "WHIT") {
+                    tokens.push(last);
+                }
+                
+                tokens.push(new Token(found, "WHIT", "NEWLINE", line));
             }
+            return true;
         },
 
         /**
@@ -164,6 +180,7 @@ TokenReader = XObject.define(
             if (stream.look() == "/" && stream.look(1) == "*") {
                 var found = stream.next(2);
                 var c = '';
+                var line = this.line;
                 while (!stream.look().eof && !(stream.look(-1) == "/" && stream.look(-2) == "*")) {
                     c = stream.next();
                     if (c == "\n") this.line++;
@@ -172,7 +189,7 @@ TokenReader = XObject.define(
                 
                 // to start doclet we allow /** or /*** but not /**/ or /****
                 if (/^\/\*\*([^\/]|\*[^*])/.test(found) && this.keepDocs) tokens.push(new Token(found, "COMM", "JSDOC", this.line));
-                else if (this.keepComments) tokens.push(new Token(found, "COMM", "MULTI_LINE_COMM", this.line));
+                else if (this.keepComments) tokens.push(new Token(found, "COMM", "MULTI_LINE_COMM", line));
                 return true;
             }
             return false;
@@ -188,13 +205,15 @@ TokenReader = XObject.define(
                 || 
                 (stream.look() == "<" && stream.look(1) == "!" && stream.look(2) == "-" && stream.look(3) == "-" && (found=stream.next(4)))
             ) {
-                
+                var line = this.line;
                 while (!stream.look().eof && !Lang.isNewline(stream.look())) {
                     found += stream.next();
                 }
-                
+                if (!stream.look().eof) {
+                    found += stream.next();
+                }
                 if (this.keepComments) {
-                    tokens.push(new Token(found, "COMM", "SINGLE_LINE_COMM", this.line));
+                    tokens.push(new Token(found, "COMM", "SINGLE_LINE_COMM", line));
                 }
                 this.line++;
                 return true;
index b5385a6..7b3328f 100644 (file)
@@ -1,17 +1,34 @@
 //<script type="text/javscript">
 
-imports['Object.js'].load(Object);
 
-JSDOC   = imports['JSDOC.js'].JSDOC;
-console = imports['console.js'].console;
-Token   = imports['JSDOC/Token.js'].Token;
-Lang    = imports['JSDOC/Lang.js'].Lang;
+XObject = imports.XObject.XObject;
+
+
+console = imports.console.console;
+Token   = imports.Token.Token;
+Lang    = imports.Lang.Lang;
+
 
 /**
-       @constructor
-*/
+ * @class TokenStream
+ * 
+ * BC notes:
+ * 
+ * nextT => nextTok
+ * lookT => lookTok
+ * 
+ */
+       
  
-TokenStream = Object.define(
+TokenStream = XObject.define(
+
+    /**
+     * @constructor
+     * 
+     * 
+     */
+
     function(tokens) {
      
         
@@ -120,8 +137,11 @@ TokenStream = Object.define(
         },
 
         /**
-            @type JSDOC.Token|JSDOC.Token[]| null!
-        */
+         *  @return {Token|null}
+         * next token (with white space)
+         */
+            
+           
         next : function(/**Number*/howMany) {
             if (typeof howMany == "undefined") howMany = 1;
             if (howMany < 1) return null;
@@ -166,16 +186,19 @@ TokenStream = Object.define(
          */
         balance : function(/**String*/start, /**String*/stop) {
             
-            start = typeof(Lang.matching(start)) == 'undefined' ? Lang.punc(start) : start;
+            
+            start = typeof(Lang.punc(start)) == 'undefined' ? start : Lang.punc(start);
             
             if (!stop) stop = Lang.matching(start);
             
             var depth = 0;
             var got = [];
             var started = false;
+            //Seed.print("START:" + start);
             //Seed.print("STOP:" + stop);
             while ((token = this.look())) {
                 if (token.is(start)) {
+              //      Seed.print("balance: START : " + depth + " " + token.data);
                     depth++;
                     started = true;
                 }
@@ -186,7 +209,8 @@ TokenStream = Object.define(
                 
                 if (token.is(stop)) {
                     depth--;
-                    if (depth == 0) return got;
+                //    Seed.print("balance: STOP: "  + depth + " " + token.data);
+                    if (depth < 1) return got;
                 }
                 if (!this.next()) break;
             }
@@ -239,11 +263,16 @@ TokenStream = Object.define(
             })
             return ret.join('');
         },
-        dump: function()
+        dump: function(start, end)
         {
-            this.tokens.forEach(function(t) {
-                print(t.toString());
-            });
+            start = Math.max(start || 0, 0);
+            end = Math.min(end || this.tokens.length, this.tokens.length);
+            var out='';
+            for (var i =start;i < end; i++) {
+                
+                out += (this.tokens[i].outData == false) ? this.tokens[i].data : this.tokens[i].outData;
+            };
+            print(out);
         }
 });
     
\ No newline at end of file
diff --git a/JSDOC/Walker2.js b/JSDOC/Walker2.js
new file mode 100644 (file)
index 0000000..05dae01
--- /dev/null
@@ -0,0 +1,935 @@
+//<Script type="text/javascript">
+XObject      = imports.XObject.XObject;
+
+Scope        = imports.Scope.Scope;
+DocComment   = imports.DocComment.DocComment;
+Symbol       = imports.Symbol.Symbol;
+
+
+/**
+* Scope stuff
+* 
+* // FIXME - I need this to do next() without doccomments..
+*/
+
+Walker2 = XObject.define(
+    function(ts) {
+        this.ts = ts;
+        this.warnings = [];
+        this.scopes = [];
+        this.indexedScopes = {};
+        this.symbols = {};
+        //this.timer = new Date() * 1;
+       
+    },
+    Object,
+    
+    {
+    /*
+        timer: 0,
+        timerPrint: function (str) {
+            var ntime = new Date() * 1;
+            var tdif =  ntime -this.timer;
+            this.timer = ntime;
+            var pref = '';
+            if (tdif > 100) { //slower ones..
+                pref = '***';
+            }
+            print(pref+'['+tdif+']'+str);
+            
+        },
+        */
+        warn: function(s) {
+            //this.warnings.push(s);
+            print("WARNING:" + htmlescape(s) + "<BR>");
+        },
+        // defaults should not be initialized here =- otherwise they get duped on new, rather than initalized..
+        warnings : false,
+        ts : false,
+        scopes : false,
+        global : false,
+        mode : "", //"BUILDING_SYMBOL_TREE",
+        braceNesting : 0,
+        indexedScopes : false,
+        munge: true,
+        symbols: false, /// object store of sumbols..
+
+
+
+
+        buildSymbolTree : function()
+        {
+            //print("<PRE>");
+            
+            this.ts.rewind();
+            this.braceNesting = 0;
+            this.scopes = [];
+            this.aliases = {};
+             
+            this.globalScope = new Scope(-1, false, -1, '$global$');
+            indexedScopes = { 0 : this.globalScope };
+            
+            this.mode = 'BUILDING_SYMBOL_TREE';
+            this.parseScope(this.globalScope);
+            
+        },
+        
+
+
+        log : function(str)
+        {
+              //print("<B>LOG:</B>" + htmlescape(str) + "<BR/>\n");
+        },
+        logR : function(str)
+        {
+                //print("<B>LOG:</B>" + str + "<BR/>");
+        },
+
+       
+        currentDoc: false,
+
+
+        parseScope : function(scope, ealiases) // parse a token stream..
+        {
+            //this.timerPrint("parseScope EnterScope"); 
+            
+            var aliases = {};
+            var fixAlias = function(str, nomore)
+            {
+                var ar = str.split('.');
+                var m = ar.shift();
+                
+                //print(str +"?=" +aliases.toSource());
+                if (aliases[m] == undefined) {
+                    return str;
+                }
+                var ret = aliases[m] + (ar.length? '.' : '' )+ ar.join('.');
+                if (nomore !== true) {
+                    ret = fixAlias(ret, true);
+                }
+                
+                
+                
+                return ret;
+            };
+
+            
+            
+            if (ealiases != undefined) {
+                // copy it down..
+                for(var i in ealiases) {
+                    aliases[i] = ealiases[i];
+                }
+                
+                
+            } else {
+                ealiases = {};
+            }
+            //print("STARTING SCOPE WITH: " + ealiases.toSource());
+            var symbol;
+            var token;
+            
+            var identifier;
+
+            var expressionBraceNesting = this.braceNesting;
+            var bracketNesting = 0;
+            var parensNesting = 0;
+           
+            
+            var l1 = '', l2 = '';
+            var scopeName ='';
+            
+            
+            var locBraceNest = 0;
+            // determines if we are in object literals...
+            
+            var isObjectLitAr = [ false ];
+            //print("SCOPE: ------------------START ----------------");
+            this.scopesIn(scope);
+            var scopeLen = this.scopes.length;
+            
+            if (this.ts.cursor < 1) {
+              // this.ts.cursor--; // hopeflly this kludge will work
+            }
+            
+            
+            //print(JSON.stringify(this.ts, null, 4)); Seed.quit();
+            
+            while (null != (token = this.ts.next())) {
+                //print("TOK"+ token.toString());
+                //  this.timerPrint("parseScope AFTER lookT: " + token.toString()); 
+                  
+                if (token.is('COMM')) {
+                      
+                 
+                    if (token.name != 'JSDOC') {
+                        //print("Walker2 : spce is not JSDOC");
+                        continue; //skip.
+                    }
+                    if (this.currentDoc) {
+                        // add it to the current scope????
+                        
+                        this.addSymbol('', true);
+                        //print ( "Unconsumed Doc: " + token.toString())
+                        //throw "Unconsumed Doc (TOKwhitespace): " + this.currentDoc.toSource();
+                    }
+                    
+                   // print ( "NEW COMMENT: " + token.toString())
+                    var newDoc = new DocComment(token.data);
+                    
+                    // it's a scope changer..
+                    if (newDoc.getTag("scope").length) {
+                        //print("Walker2 : doctag changes scope");
+                        //throw "done";
+                        scope.ident = '$private$|' + newDoc.getTag("scope")[0].desc;
+                        continue;
+                    }
+                    
+                    // it's a scope changer..
+                    if (newDoc.getTag("scopeAlias").length) {
+                        //print(newDoc.getTag("scopeAlias").toSource());
+                        // @scopeAlias a=b
+                        //print("Walker2 : doctag changes scope (alias)");
+                        var sal = newDoc.getTag("scopeAlias")[0].desc.split("=");
+                        aliases[sal[0]] = sal[1];
+                        
+                        continue;
+                    }
+                    
+                    
+                    /// got a  doc comment..
+                    //token.data might be this.??? (not sure though)
+                    //print("Walker2 : setting currentDoc");
+                    this.currentDoc = newDoc;
+                    continue;
+                }
+                
+                // catch the various issues .. - scoe changes or doc actions..
+                
+              
+                
+                // things that stop comments carrying on...??
+                
+                if (this.currentDoc && (
+                        token.data == ';' || 
+                        token.data == '}')) {
+                    this.addSymbol('', true);
+                    //throw "Unconsumed Doc ("+ token.toString() +"): " + this.currentDoc.toSource();
+                }
+                    
+                
+                // the rest are scoping issues...
+                
+                // var a = b;
+                
+                 if (token.name == 'VAR' &&
+                 
+                        this.ts.lookTok(1).type == 'NAME' &&
+                        this.ts.lookTok(2).data == '=' &&
+                        this.ts.lookTok(3).type == 'NAME'  &&
+                        this.ts.lookTok(4).data == ';'  
+                        
+                 
+                 ) {
+                    //print("SET ALIAS:" + this.ts.lookTok(1).data +'=' + this.ts.lookTok(3).data);
+                     
+                    aliases[this.ts.lookTok(1).data] = this.ts.lookTok(3).data;
+                    
+                
+                }
+                
+                if ((token.data == 'eval') || /\.eval$/.test(token.data)) {
+                    this.currentDoc = false;
+                    continue;
+                }
+              
+                // extends scoping  *** not sure if the can be x = Roo.apply(....)
+                // xxx.extends(a,b, {
+                    // $this$=b|b.prototype
+                // xxx.apply(a, {
+                    // a  << scope
+                // xxx.applyIf(a, {
+                    // a  << scope
+                if (token.type == 'NAME') {
+                    
+                    //print("TOK(ident)"+ token.toString());
+                     
+                    if (/\.extend$/.test(token.data) &&
+                        this.ts.lookTok(1).data == '(' &&
+                        this.ts.lookTok(2).type == 'NAME' &&
+                        this.ts.lookTok(3).data == ',' &&
+                        this.ts.lookTok(4).type == 'NAME' &&
+                        this.ts.lookTok(5).data == ',' &&
+                        this.ts.lookTok(6).data == '{' 
+                           
+                        ) {
+                        // ignore test for ( a and ,
+                        this.ts.nextTok(); /// (
+                        token = this.ts.nextTok(); // a
+                        scopeName = token.data;
+                        
+                        if (this.currentDoc) {
+