--- /dev/null
+//<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
--- /dev/null
+//<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;
+}
--- /dev/null
+//<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
--- /dev/null
+//<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;
+}
--- /dev/null
+//<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
--- /dev/null
+//<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) {
+ this.addSymbol(scopeName,false,'OBJECT');
+
+ }
+ this.ts.nextTok(); // ,
+ this.ts.nextTok(); // b
+
+
+ this.ts.nextTok(); // ,
+ token = this.ts.nextTok(); // {
+
+ scopeName = fixAlias(scopeName);
+
+ var fnScope = new Scope(this.braceNesting, scope, token.n,
+ '$this$=' + scopeName + '|'+scopeName+'.prototype');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+ }
+
+ // a = Roo.extend(parentname, {
+
+ if (/\.extend$/.test(token.data) &&
+ this.ts.lookTok(-2).type == 'NAME' &&
+ this.ts.lookTok(-1).data == '=' &&
+ this.ts.lookTok(1).data == '(' &&
+ this.ts.lookTok(2).type == 'NAME' &&
+ this.ts.lookTok(3).data == ',' &&
+ this.ts.lookTok(4).data == '{'
+ ) {
+ // ignore test for ( a and ,
+ token = this.ts.lookTok(-2);
+ scopeName = token.data;
+ if (this.currentDoc) {
+ this.addSymbol(scopeName,false,'OBJECT');
+
+ }
+ this.ts.nextTok(); /// (
+ this.ts.nextTok(); // parent
+
+ this.ts.nextTok(); // ,
+ token = this.ts.nextTok(); // {
+
+
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n,
+ '$this$=' + scopeName + '|'+scopeName+'.prototype');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+ }
+
+
+ // apply ( XXXX, {
+ /*
+ print(JSON.stringify([
+ token.data,
+ this.ts.lookTok(1).data ,
+ this.ts.lookTok(2).type ,
+ this.ts.lookTok(3).data ,
+ this.ts.lookTok(4).data
+ ], null, 4));
+ */
+
+ if (/\.(applyIf|apply)$/.test(token.data) &&
+ this.ts.lookTok(1).data == '(' &&
+ this.ts.lookTok(2).type == 'NAME' &&
+ this.ts.lookTok(3).data == ',' &&
+ this.ts.lookTok(4).data == '{'
+
+ ) {
+ this.ts.nextTok(); /// (
+
+ //print("GOT : applyIF!");
+
+ token = this.ts.nextTok(); // b
+ scopeName = token.data;
+
+
+ if (this.currentDoc) {
+ this.addSymbol(scopeName,false,'OBJECT');
+ }
+
+
+
+ this.ts.nextTok(); /// ,
+ this.ts.nextTok(); // {
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n, scopeName);
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+ }
+
+
+ // xxx = new yyy ( {
+
+ // change scope to xxxx
+ /*
+ print(JSON.stringify([
+ this.ts.lookTok(1).data ,
+ this.ts.lookTok(2).name ,
+ this.ts.lookTok(3).type ,
+ this.ts.lookTok(4).data ,
+ this.ts.lookTok(5).data
+ ], null, 4));
+ */
+ if ( this.ts.lookTok(1).data == '=' &&
+ this.ts.lookTok(2).name == 'NEW' &&
+ this.ts.lookTok(3).type == 'NAME' &&
+ this.ts.lookTok(4).data == '(' &&
+ this.ts.lookTok(5).data == '{'
+ ) {
+ scopeName = token.data;
+ if (this.currentDoc) {
+ this.addSymbol(scopeName,false,'OBJECT');
+
+ }
+
+ this.ts.nextTok(); /// =
+ this.ts.nextTok(); /// new
+ this.ts.nextTok(); /// yyy
+ this.ts.nextTok(); /// (
+ this.ts.nextTok(); /// {
+
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n, scopeName);
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+
+ continue; // no more processing..
+ }
+
+
+
+
+
+
+
+ // eval can be prefixed with a hint hider for the compresser..
+
+
+ if (this.currentDoc) {
+ //print(token.toString());
+
+ // ident : function ()
+ // ident = function ()
+ var atype = 'OBJECT';
+
+ if (((this.ts.lookTok(1).data == ':' )|| (this.ts.lookTok(1).data == '=')) &&
+ (this.ts.lookTok(2).name == "FUNCTION")
+ ) {
+ // this.ts.nextTok();
+ // this.ts.nextTok();
+ atype = 'FUNCTION';
+ }
+
+ //print("ADD SYM:" + atype + ":" + token.toString() + this.ts.lookTok(1).toString() + this.ts.lookTok(2).toString());
+
+ this.addSymbol(
+ this.ts.lookTok(-1).data == '.' ? token.data : fixAlias(token.data),
+ false,
+ atype);
+
+ this.currentDoc = false;
+
+
+ }
+
+
+ continue; // dont care about other idents..
+
+ }
+
+ //print ("NOT NAME");
+
+
+ if (token.type == "STRN") { // THIS WILL NOT HAPPEN HERE?!!?
+ if (this.currentDoc) {
+ this.addSymbol(token.data.substring(1,token.data.length-1),false,'OBJECT');
+
+ }
+ }
+
+ // really we only have to deal with object constructs and function calls that change the scope...
+
+
+ if (token.name == 'FUNCTION') {
+ //print("GOT FUNCTION");
+ // see if we have an unconsumed doc...
+
+ if (this.currentDoc) {
+ throw {
+ name: "ArgumentError",
+ message: "Unhandled doc (TOKfunction)" + token.toString()
+ };
+
+ //this.addSymbol(this.currentDoc.getTag('class')[0].name, true);
+
+ //throw "Unconsumed Doc: (TOKrbrace)" + this.currentDoc.toSource();
+ }
+
+
+
+
+
+ /// foo = function() {} << really it set's the 'this' scope to foo.prototype
+ //$this$=foo.prototype|$private$|foo.prototype
+
+ if (
+ (this.ts.lookTok(-1).data == '=') &&
+ (this.ts.lookTok(-2).type == 'NAME')
+ ) {
+ scopeName = this.ts.lookTok(-2).data;
+ this.ts.balance('(');
+ token = this.ts.nextTok(); // should be {
+ //print("FOO=FUNCITON() {}" + this.ts.context() + "\n" + token.toString());
+
+
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n,
+ '$this$='+scopeName+'.prototype|$private$|'+scopeName+'.prototype');
+
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ //scope = fnScope;
+ //this.scopesIn(fnScope);
+ this.parseScope(fnScope, aliases);
+
+
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+
+ }
+
+
+ // foo = new function() {}
+ // is this actually used much!?!?!
+ //$private$
+
+ if (
+ (this.ts.lookTok(-1).name == 'NEW') &&
+ (this.ts.lookTok(-2).data == '=') &&
+ (this.ts.lookTok(-3).type = 'FUNCTION')
+ ) {
+ //scopeName = this.ts.look(-3).data;
+ this.ts.balance("(");
+ token = this.ts.nextTok(); // should be {
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n, '$private$');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ //scope = fnScope;
+ //this.scopesIn(fnScope);
+ this.parseScope(fnScope, aliases);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+
+ }
+
+
+ ///==== check/set isObjectLitAr ??
+
+
+ // foo: function() {}
+ // no change to scoping..
+
+ //print("checking for : function() {");
+ //print( [this.ts.lookTok(-3).type , this.ts.lookTok(-2).type , this.ts.lookTok(-1).type ].join(":"));
+ if (
+ (this.ts.lookTok(-1).data == ':') &&
+ (this.ts.lookTok(-2).type == 'NAME') &&
+ (this.ts.lookTok(-3).data == '(' || this.ts.lookTok(-3).data== ',')
+ ) {
+ //print("got for : function() {");
+
+ //scopeName = this.ts.look(-3).data;
+ this.ts.balance('(');
+ //print(token.toString())
+ token = this.ts.nextTok(); // should be {
+ //print(token.toString())
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n, '');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ //scope = fnScope;
+ //this.scopesIn(fnScope);
+ this.parseScope(fnScope, aliases);
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+ }
+ /// function foo() {} << really it set's the 'this' scope to foo.prototype
+ //$this$=foo|$private$
+ //$this$=foo
+
+ if (
+ (this.ts.lookTok(1).type == 'NAME')
+ ) {
+ //scopeName = this.ts.look(-3).data;
+ this.ts.balance('(');
+ token = this.ts.nextTok(); // should be {
+
+ var fnScope = new Scope(this.braceNesting, scope, token.n, '');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ //scope = fnScope;
+ //this.scopesIn(fnScope);
+ this.parseScope(fnScope, aliases);
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+ }
+
+
+ // foo = new (function() { }
+ // (function() { }
+ // RETURN function(...) {
+
+ if (
+ // (this.ts.lookTok(-1).tokN == Script.TOKlparen) &&
+ (this.ts.lookTok(1).name != 'NAME')
+
+ // (this.ts.lookTok(-2).tokN == Script.TOKnew) &&
+ // (this.ts.lookTok(-3).tokN == Script.TOKassign) &&
+ // (this.ts.lookTok(-4).tokN == Script.TOKidentifier)
+ ) {
+ //scopeName = this.ts.look(-3).data;
+ this.ts.balance('(');
+ token = this.ts.nextTok(); // should be {
+ var fnScope = new Scope(this.braceNesting, scope, token.n, '$private$');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ //scope = ;
+ //this.scopesIn(fnScope);
+ this.parseScope(fnScope, aliases);
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+
+
+ }
+
+
+ throw {
+ name: "ArgumentError",
+ message: "dont know how to handle function syntax??\n" +
+ token.toString()
+ };
+
+
+ continue;
+
+
+
+
+ } // end checking for TOKfunction
+
+ if (token.data == '{') {
+
+ // foo = { // !var!!!
+ //$this$=foo|Foo
+
+
+ if (
+ (this.ts.lookTok(-1).data == '=') &&
+ (this.ts.lookTok(-2).type == 'NAME') &&
+ (this.ts.lookTok(-3).nane != 'VAR')
+ ) {
+
+ scopeName = this.ts.look(-2).data;
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n,
+ '$this$='+scopeName + '|'+scopeName
+ );
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+ }
+ // foo : {
+ // ?? add |foo| ????
+
+ //print("GOT LBRACE : check for :");
+ if (
+ (this.ts.lookTok(-1).data == ':') &&
+ (this.ts.lookTok(-2).type == 'NAME') &&
+ (this.ts.lookTok(-3).name != 'VAR')
+ ) {
+
+ scopeName = this.ts.lookTok(-2).data;
+ scopeName = fixAlias(scopeName);
+ var fnScope = new Scope(this.braceNesting, scope, token.n, scopeName);
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue; // no more processing..
+ }
+ var fnScope = new Scope(this.braceNesting, scope, token.n, '');
+ this.indexedScopes[this.ts.cursor] = fnScope;
+ scope = fnScope;
+ this.scopesIn(fnScope);
+
+ locBraceNest++;
+ //print(">>" +locBraceNest);
+ continue;
+
+ }
+ if (token.data == '}') {
+
+
+ if (this.currentDoc) {
+ this.addSymbol('', true);
+
+ //throw "Unconsumed Doc: (TOKrbrace)" + this.currentDoc.toSource();
+ }
+
+
+ locBraceNest--;
+
+ //assert braceNesting >= scope.getBraceNesting();
+ var closescope = this.scopeOut();
+ scope = this.scopes[this.scopes.length-1];
+ //print("<<:" + locBraceNest)
+ //print("<<<<<< " + locBraceNest );
+ if (locBraceNest < 0) {
+ // print("POPED OF END OF SCOPE!");
+ ///this.scopeOut();
+ //var ls = this.scopeOut();
+ //ls.getUsedSymbols();
+ return;
+ }
+ continue;
+ }
+
+
+ }
+
+
+ },
+
+
+ addSymbol: function(lastIdent, appendIt, atype )
+ {
+ //print("Walker.addSymbol : " + lastIdent);
+ // print("Walker.curdoc: " + JSON.stringify(this.currentDoc, null,4));
+
+ /*if (!this.currentDoc.tags.length) {
+
+
+ //print(this.currentDoc.toSource());
+ // this.currentDoc = false;
+
+ print("SKIP ADD SYM: no tags");
+ print(this.currentDoc.src);
+ return;
+ }
+ */
+ if (this.currentDoc.getTag('private').length) {
+
+
+ //print(this.currentDoc.toSource());
+ this.currentDoc = false;
+ //print("SKIP ADD SYM: it's private");
+ return;
+ }
+
+ var token = this.ts.lookTok(0);
+ if (typeof(appendIt) == 'undefined') {
+ appendIt= false;
+ }
+ // print(this.currentDoc.toSource(););
+ if (this.currentDoc.getTag('event').length) {
+ //?? why does it end up in desc - and not name/...
+ //print(this.currentDoc.getTag('event')[0]);
+ lastIdent = '*' + this.currentDoc.getTag('event')[0].desc;
+ //lastIdent = '*' + lastIdent ;
+ }
+ if (!lastIdent.length && this.currentDoc.getTag('property').length) {
+ lastIdent = this.currentDoc.getTag('property')[0].name;
+ //lastIdent = '*' + lastIdent ;
+ }
+
+ var _s = lastIdent;
+ if (!/\./.test(_s)) {
+
+ //print("WALKER ADDsymbol: " + lastIdent);
+
+ var s = [];
+ for (var i = 0; i < this.scopes.length;i++) {
+ s.push(this.scopes[i].ident);
+ }
+ s.push(lastIdent);
+
+ //print("FULLSCOPE: " + JSON.stringify(s));
+
+
+ var s = s.join('|').split('|');
+ //print("FULLSCOPE: " + s);
+ // print("Walker:ADDSymbol: " + s.join('|') );
+ var _t = '';
+ _s = '';
+
+ /// fixme - needs
+ for (var i = 0; i < s.length;i++) {
+
+ if (!s[i].length) {
+ continue;
+ }
+ if ((s[i] == '$private$') || (s[i] == '$global$')) {
+ _s = '';
+ continue;
+ }
+ if (s[i].substring(0,6) == '$this$') {
+ var ts = s[i].split('=');
+ _t = ts[1];
+ _s = ''; // ??? VERY QUESTIONABLE!!!
+ continue;
+ }
+ // when to use $this$ (probabl for events)
+ _s += _s.length ? '.' : '';
+ _s += s[i];
+ }
+ //print("FULLSCOPE: s , t : " + _s +', ' + _t);
+
+ /// calc scope!!
+ //print("ADDING SYMBOL: "+ s.join('|') +"\n"+ _s + "\n" +Script.prettyDump(this.currentDoc.toSource()));
+ //print("Walker.addsymbol - add : " + _s);
+ if (appendIt && !lastIdent.length) {
+
+ // append, and no symbol???
+
+ // see if it's a @class
+ if (this.currentDoc.getTag('class').length) {
+ _s = this.currentDoc.getTag('class')[0].desc;
+ var symbol = new Symbol(_s, [], "CONSTRUCTOR", this.currentDoc);
+ Parser = imports.Parser.Parser;
+ Parser.addSymbol(symbol);
+ this.symbols[_s] = symbol;
+ return;
+ }
+
+ // if (this.currentDoc.getTag('property').length) {
+ // print(Script.pretStringtyDump(this.currentDoc.toSource));
+ // throw "Add Prop?";
+ //}
+
+ _s = _s.replace(/\.prototype.*$/, '');
+ if (typeof(this.symbols[_s]) == 'undefined') {
+ //print("Symbol:" + _s);
+ //print(this.currentDoc.src);
+
+ //throw {
+ // name: "ArgumentError",
+ // message: "Trying to append symbol '" + _s + "', but no doc available\n" +
+ // this.ts.lookTok(0).toString()
+ //};
+ this.currentDoc = false;
+ return;
+
+ }
+
+ for (var i =0; i < this.currentDoc.tags.length;i++) {
+ this.symbols[_s].addDocTag(this.currentDoc.tags[i]);
+ }
+ this.currentDoc = false;
+ return;
+ }
+ }
+ //print("Walker.addsymbol - chkdup: " + _s);
+ if (typeof(this.symbols[_s]) != 'undefined') {
+
+ if (this.symbols[_s].comment.hasTags) {
+ // then existing comment doesnt has tags
+ //throw {
+ // name: "ArgumentError",
+ // message:"DUPLICATE Symbol " + _s + "\n" + token.toString()
+ //};
+ return;
+ }
+ // otherwise existing comment has tags - overwrite..
+
+
+ }
+ //print("Walker.addsymbol - ATYPE: " + _s);
+
+ if (typeof(atype) == "undefined") {
+ atype = 'OBJECT'; //this.currentDoc.getTag('class').length ? 'OBJECT' : 'FUNCTION';;
+ }
+
+ //print("Walker.addsymbol - add : ");
+ var symbol = new Symbol(_s, [], atype, this.currentDoc);
+ Parser = imports.Parser.Parser;
+ Parser.addSymbol(symbol);
+ this.symbols[_s] = symbol;
+
+ this.currentDoc = false;
+
+ },
+
+
+
+
+ scopesIn : function(s)
+ {
+ this.scopes.push(s);
+ //print(">>>" + this.ts.context() + "\n>>>"+this.scopes.length+":" +this.scopeListToStr());
+
+ },
+ scopeOut : function()
+ {
+
+ // print("<<<" + this.ts.context() + "\n<<<"+this.scopes.length+":" +this.scopeListToStr());
+ return this.scopes.pop();
+
+ },
+
+ scopeListToStr : function()
+ {
+ var s = [];
+ for (var i = 0; i < this.scopes.length;i++) {
+ s.push(this.scopes[i].ident);
+ }
+ return s.join('\n\t');
+
+ }
+
+
+
+
+});
\ No newline at end of file