aboutsummaryrefslogtreecommitdiff
path: root/tools/jsdoc-toolkit-2.4.0/app/lib
diff options
context:
space:
mode:
Diffstat (limited to 'tools/jsdoc-toolkit-2.4.0/app/lib')
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC.js106
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocComment.js204
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocTag.js294
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsDoc.js140
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsPlate.js109
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Lang.js144
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Parser.js146
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/PluginManager.js33
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Symbol.js644
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/SymbolSet.js243
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TextStream.js41
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Token.js18
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenReader.js332
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenStream.js133
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Util.js32
-rw-r--r--tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Walker.js507
16 files changed, 3126 insertions, 0 deletions
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC.js
new file mode 100644
index 0000000..5de7b9e
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC.js
@@ -0,0 +1,106 @@
+/**
+ @overview
+ @date $Date: 2010-06-13 22:02:44 +0100 (Sun, 13 Jun 2010) $
+ @version $Revision: 837 $
+ @location $HeadURL: https://jsdoc-toolkit.googlecode.com/svn/tags/jsdoc_toolkit-2.4.0/jsdoc-toolkit/app/lib/JSDOC.js $
+ @name JSDOC.js
+ */
+
+/**
+ This is the main container for the JSDOC application.
+ @namespace
+*/
+JSDOC = {
+};
+
+/**
+ @requires Opt
+ */
+if (typeof arguments == "undefined") arguments = [];
+JSDOC.opt = Opt.get(
+ arguments,
+ {
+ a: "allfunctions",
+ c: "conf",
+ d: "directory",
+ "D[]": "define",
+ e: "encoding",
+ "E[]": "exclude",
+ h: "help",
+ m: "multiple",
+ n: "nocode",
+ o: "out",
+ p: "private",
+ q: "quiet",
+ r: "recurse",
+ S: "securemodules",
+ s: "suppress",
+ t: "template",
+ T: "testmode",
+ u: "unique",
+ v: "verbose",
+ x: "ext"
+ }
+);
+
+/** The current version string of this application. */
+JSDOC.VERSION = "2.4.0";
+
+/** Print out usage information and quit. */
+JSDOC.usage = function() {
+ print("USAGE: java -jar jsrun.jar app/run.js [OPTIONS] <SRC_DIR> <SRC_FILE> ...");
+ print("");
+ print("OPTIONS:");
+ print(" -a or --allfunctions\n Include all functions, even undocumented ones.\n");
+ print(" -c or --conf\n Load a configuration file.\n");
+ print(" -d=<PATH> or --directory=<PATH>\n Output to this directory (defaults to \"out\").\n");
+ print(" -D=\"myVar:My value\" or --define=\"myVar:My value\"\n Multiple. Define a variable, available in JsDoc as JSDOC.opt.D.myVar.\n");
+ print(" -e=<ENCODING> or --encoding=<ENCODING>\n Use this encoding to read and write files.\n");
+ print(" -E=\"REGEX\" or --exclude=\"REGEX\"\n Multiple. Exclude files based on the supplied regex.\n");
+ print(" -h or --help\n Show this message and exit.\n");
+ print(" -m or --multiples\n Don't warn about symbols being documented more than once.\n");
+ print(" -n or --nocode\n Ignore all code, only document comments with @name tags.\n");
+ print(" -o=<PATH> or --out=<PATH>\n Print log messages to a file (defaults to stdout).\n");
+ print(" -p or --private\n Include symbols tagged as private, underscored and inner symbols.\n");
+ print(" -q or --quiet\n Do not output any messages, not even warnings.\n");
+ print(" -r=<DEPTH> or --recurse=<DEPTH>\n Descend into src directories.\n");
+ print(" -s or --suppress\n Suppress source code output.\n");
+ print(" -S or --securemodules\n Use Secure Modules mode to parse source code.\n");
+ print(" -t=<PATH> or --template=<PATH>\n Required. Use this template to format the output.\n");
+ print(" -T or --test\n Run all unit tests and exit.\n");
+ print(" -u or --unique\n Force file names to be unique, but not based on symbol names.\n");
+ print(" -v or --verbose\n Provide verbose feedback about what is happening.\n");
+ print(" -x=<EXT>[,EXT]... or --ext=<EXT>[,EXT]...\n Scan source files with the given extension/s (defaults to js).\n");
+
+ quit();
+}
+
+/*t:
+ plan(4, "Testing JSDOC namespace.");
+
+ is(
+ typeof JSDOC,
+ "object",
+ "JSDOC.usage is a function."
+ );
+
+ is(
+ typeof JSDOC.VERSION,
+ "string",
+ "JSDOC.VERSION is a string."
+ );
+
+ is(
+ typeof JSDOC.usage,
+ "function",
+ "JSDOC.usage is a function."
+ );
+
+ is(
+ typeof JSDOC.opt,
+ "object",
+ "JSDOC.opt is a object."
+ );
+ */
+
+if (this.IO) IO.includeDir("lib/JSDOC/");
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocComment.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocComment.js
new file mode 100644
index 0000000..4b21cd7
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocComment.js
@@ -0,0 +1,204 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ Create a new DocComment. This takes a raw documentation comment,
+ and wraps it in useful accessors.
+ @class Represents a documentation comment object.
+ */
+JSDOC.DocComment = function(/**String*/comment) {
+ this.init();
+ if (typeof comment != "undefined") {
+ this.parse(comment);
+ }
+}
+
+JSDOC.DocComment.prototype.init = function() {
+ this.isUserComment = true;
+ this.src = "";
+ this.meta = "";
+ this.tagTexts = [];
+ this.tags = [];
+}
+
+/**
+ @requires JSDOC.DocTag
+ */
+JSDOC.DocComment.prototype.parse = function(/**String*/comment) {
+ if (comment == "") {
+ comment = "/** @desc */";
+ this.isUserComment = false;
+ }
+
+ this.src = JSDOC.DocComment.unwrapComment(comment);
+
+ 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;
+ }
+
+ if (typeof JSDOC.PluginManager != "undefined") {
+ JSDOC.PluginManager.run("onDocCommentSrc", this);
+ }
+
+ this.fixDesc();
+
+ this.src = JSDOC.DocComment.shared+"\n"+this.src;
+
+ this.tagTexts =
+ this.src
+ .split(/(^|[\r\n])\s*@/)
+ .filter(function($){return $.match(/\S/)});
+
+ /**
+ The tags found in the comment.
+ @type JSDOC.DocTag[]
+ */
+ this.tags = this.tagTexts.map(function($){return new JSDOC.DocTag($)});
+
+ if (typeof JSDOC.PluginManager != "undefined") {
+ JSDOC.PluginManager.run("onDocCommentTags", this);
+ }
+}
+
+/*t:
+ plan(5, "testing JSDOC.DocComment");
+ requires("../frame/String.js");
+ requires("../lib/JSDOC/DocTag.js");
+
+ var com = new JSDOC.DocComment("/**@foo some\n* comment here*"+"/");
+ is(com.tagTexts[0], "foo some\ncomment here", "first tag text is found.");
+ is(com.tags[0].title, "foo", "the title is found in a comment with one tag.");
+
+ var com = new JSDOC.DocComment("/** @foo first\n* @bar second*"+"/");
+ is(com.getTag("bar").length, 1, "getTag() returns one tag by that title.");
+
+ JSDOC.DocComment.shared = "@author John Smith";
+ var com = new JSDOC.DocComment("/**@foo some\n* comment here*"+"/");
+ is(com.tags[0].title, "author", "shared comment is added.");
+ is(com.tags[1].title, "foo", "shared comment is added to existing tag.");
+*/
+
+/**
+ If no @desc tag is provided, this function will add it.
+ */
+JSDOC.DocComment.prototype.fixDesc = function() {
+ if (this.meta && this.meta != "@+") return;
+ if (/^\s*[^@\s]/.test(this.src)) {
+ this.src = "@desc "+this.src;
+ }
+}
+
+/*t:
+ plan(5, "testing JSDOC.DocComment#fixDesc");
+
+ var com = new JSDOC.DocComment();
+
+ com.src = "this is a desc\n@author foo";
+ com.fixDesc();
+ is(com.src, "@desc this is a desc\n@author foo", "if no @desc tag is provided one is added.");
+
+ com.src = "x";
+ com.fixDesc();
+ is(com.src, "@desc x", "if no @desc tag is provided one is added to a single character.");
+
+ com.src = "\nx";
+ com.fixDesc();
+ is(com.src, "@desc \nx", "if no @desc tag is provided one is added to return and character.");
+
+ com.src = " ";
+ com.fixDesc();
+ is(com.src, " ", "if no @desc tag is provided one is not added to just whitespace.");
+
+ com.src = "";
+ com.fixDesc();
+ is(com.src, "", "if no @desc tag is provided one is not added to empty.");
+*/
+
+/**
+ Remove slash-star comment wrapper from a raw comment string.
+ @type String
+ */
+JSDOC.DocComment.unwrapComment = function(/**String*/comment) {
+ if (!comment) return "";
+ var unwrapped = comment.replace(/(^\/\*\*|\*\/$)/g, "").replace(/^\s*\* ?/gm, "");
+ return unwrapped;
+}
+
+/*t:
+ plan(5, "testing JSDOC.DocComment.unwrapComment");
+
+ var com = "/**x*"+"/";
+ var unwrapped = JSDOC.DocComment.unwrapComment(com);
+ is(unwrapped, "x", "a single character jsdoc is found.");
+
+ com = "/***x*"+"/";
+ unwrapped = JSDOC.DocComment.unwrapComment(com);
+ is(unwrapped, "x", "three stars are allowed in the opener.");
+
+ com = "/****x*"+"/";
+ unwrapped = JSDOC.DocComment.unwrapComment(com);
+ is(unwrapped, "*x", "fourth star in the opener is kept.");
+
+ com = "/**x\n * y\n*"+"/";
+ unwrapped = JSDOC.DocComment.unwrapComment(com);
+ is(unwrapped, "x\ny\n", "leading stars and spaces are trimmed.");
+
+ com = "/**x\n * y\n*"+"/";
+ unwrapped = JSDOC.DocComment.unwrapComment(com);
+ is(unwrapped, "x\n y\n", "only first space after leading stars are trimmed.");
+*/
+
+/**
+ Provides a printable version of the comment.
+ @type String
+ */
+JSDOC.DocComment.prototype.toString = function() {
+ return this.src;
+}
+
+/*t:
+ plan(1, "testing JSDOC.DocComment#fixDesc");
+ var com = new JSDOC.DocComment();
+ com.src = "foo";
+ is(""+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[]
+ */
+JSDOC.DocComment.prototype.getTag = function(/**String*/tagTitle) {
+ return this.tags.filter(function($){return $.title == tagTitle});
+}
+
+JSDOC.DocComment.prototype.deleteTag = function(/**String*/tagTitle) {
+ this.tags = this.tags.filter(function($){return $.title != tagTitle})
+}
+
+/*t:
+ plan(1, "testing JSDOC.DocComment#getTag");
+ requires("../frame/String.js");
+ requires("../lib/JSDOC/DocTag.js");
+
+ var com = new JSDOC.DocComment("/**@foo some\n* @bar\n* @bar*"+"/");
+ is(com.getTag("bar").length, 2, "getTag returns expected number of tags.");
+*/
+
+/**
+ Used to store the currently shared tag text.
+*/
+JSDOC.DocComment.shared = "";
+
+/*t:
+ plan(2, "testing JSDOC.DocComment.shared");
+ requires("../frame/String.js");
+ requires("../lib/JSDOC/DocTag.js");
+
+ JSDOC.DocComment.shared = "@author Michael";
+
+ var com = new JSDOC.DocComment("/**@foo\n* @foo*"+"/");
+ is(com.getTag("author").length, 1, "getTag returns shared tag.");
+ is(com.getTag("foo").length, 2, "getTag returns unshared tags too.");
+*/ \ No newline at end of file
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocTag.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocTag.js
new file mode 100644
index 0000000..77ec07c
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/DocTag.js
@@ -0,0 +1,294 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ @constructor
+ */
+JSDOC.DocTag = function(src) {
+ this.init();
+ if (typeof src != "undefined") {
+ this.parse(src);
+ }
+}
+
+/**
+ Create and initialize the properties of this.
+ */
+JSDOC.DocTag.prototype.init = function() {
+ this.title = "";
+ this.type = "";
+ this.name = "";
+ this.isOptional = false;
+ this.defaultValue = "";
+ this.desc = "";
+
+ return this;
+}
+
+/**
+ Populate the properties of this from the given tag src.
+ @param {string} src
+ */
+JSDOC.DocTag.prototype.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 == "config") { // @config is deprecated
+ src = this.nibbleName(src);
+ }
+ }
+ catch(e) {
+ if (LOG) 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.
+ */
+JSDOC.DocTag.prototype.toString = function() {
+ return this.desc;
+}
+
+/*t:
+ plan(1, "testing JSDOC.DocTag#toString");
+
+ var tag = new JSDOC.DocTag("param {object} date A valid date.");
+ is(""+tag, "A valid date.", "stringifying a tag returns the desc.");
+ */
+
+/**
+ Find and shift off the title of a tag.
+ @param {string} src
+ @return src
+ */
+JSDOC.DocTag.prototype.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;
+}
+
+/*t:
+ plan(8, "testing JSDOC.DocTag#nibbleTitle");
+
+ var tag = new JSDOC.DocTag();
+
+ tag.init().nibbleTitle("aTitleGoesHere");
+ is(tag.title, "aTitleGoesHere", "a title can be found in a single-word string.");
+
+ var src = tag.init().nibbleTitle("aTitleGoesHere and the rest");
+ is(tag.title, "aTitleGoesHere", "a title can be found in a multi-word string.");
+ is(src, "and the rest", "the rest is returned when the title is nibbled off.");
+
+ src = tag.init().nibbleTitle("");
+ is(tag.title, "", "given an empty string the title is empty.");
+ is(src, "", "the rest is empty when the tag is empty.");
+
+ var src = tag.init().nibbleTitle(" aTitleGoesHere\n a description");
+ is(tag.title, "aTitleGoesHere", "leading and trailing spaces are not part of the title.");
+ is(src, " a description", "leading spaces (less one) are part of the description.");
+
+ tag.init().nibbleTitle("a.Title::Goes_Here foo");
+ is(tag.title, "a.Title::Goes_Here", "titles with punctuation are allowed.");
+ */
+
+/**
+ Find and shift off the type of a tag.
+ @requires frame/String.js
+ @param {string} src
+ @return src
+ */
+JSDOC.DocTag.prototype.nibbleType = function(src) {
+ if (typeof src != "string") throw "src must be a string not "+(typeof src);
+
+ if (src.match(/^\s*\{/)) {
+ var typeRange = src.balance("{", "}");
+ 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;
+}
+
+/*t:
+ plan(5, "testing JSDOC.DocTag.parser.nibbleType");
+ requires("../frame/String.js");
+
+ var tag = new JSDOC.DocTag();
+
+ tag.init().nibbleType("{String[]} aliases");
+ is(tag.type, "String[]", "type can have non-alpha characters.");
+
+ tag.init().nibbleType("{ aTypeGoesHere } etc etc");
+ is(tag.type, "aTypeGoesHere", "type is trimmed.");
+
+ tag.init().nibbleType("{ oneType, twoType ,\n threeType } etc etc");
+ is(tag.type, "oneType|twoType|threeType", "multiple types can be separated by commas.");
+
+ var error;
+ try { tag.init().nibbleType("{widget foo"); }
+ catch(e) { error = e; }
+ is(typeof error, "string", "malformed tag type throws error.");
+ isnt(error.indexOf("Malformed"), -1, "error message tells tag is malformed.");
+ */
+
+/**
+ Find and shift off the name of a tag.
+ @requires frame/String.js
+ @param {string} src
+ @return src
+ */
+JSDOC.DocTag.prototype.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 = src.balance("[", "]");
+ 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;
+}
+
+/*t:
+ requires("../frame/String.js");
+ plan(9, "testing JSDOC.DocTag.parser.nibbleName");
+
+ var tag = new JSDOC.DocTag();
+
+ tag.init().nibbleName("[foo] This is a description.");
+ is(tag.isOptional, true, "isOptional syntax is detected.");
+ is(tag.name, "foo", "optional param name is found.");
+
+ tag.init().nibbleName("[foo] This is a description.");
+ is(tag.isOptional, true, "isOptional syntax is detected when no type.");
+ is(tag.name, "foo", "optional param name is found when no type.");
+
+ tag.init().nibbleName("[foo=7] This is a description.");
+ is(tag.name, "foo", "optional param name is found when default value.");
+ is(tag.defaultValue, 7, "optional param default value is found when default value.");
+
+ //tag.init().nibbleName("[foo= a value] This is a description.");
+ //is(tag.defaultValue, " a value", "optional param default value is found when default value has spaces (issue #112).");
+
+ tag.init().nibbleName("[foo=[]] This is a description.");
+ is(tag.defaultValue, "[]", "optional param default value is found when default value is [] (issue #95).");
+
+ tag.init().nibbleName("[foo=a=b] This is a description.");
+ is(tag.name, "foo", "optional param name is found when default value is a=b.");
+ is(tag.defaultValue, "a=b", "optional param default value is found when default value is a=b.")
+ */
+
+/*t:
+ plan(32, "Testing JSDOC.DocTag.parser.");
+ requires("../frame/String.js");
+
+ var tag = new JSDOC.DocTag();
+
+ is(typeof tag, "object", "JSDOC.DocTag.parser with an empty string returns an object.");
+ is(typeof tag.title, "string", "returned object has a string property 'title'.");
+ is(typeof tag.type, "string", "returned object has a string property 'type'.");
+ is(typeof tag.name, "string", "returned object has a string property 'name'.");
+ is(typeof tag.defaultValue, "string", "returned object has a string property 'defaultValue'.");
+ is(typeof tag.isOptional, "boolean", "returned object has a boolean property 'isOptional'.");
+ is(typeof tag.desc, "string", "returned object has a string property 'desc'.");
+
+ tag = new JSDOC.DocTag("param {widget} foo");
+ is(tag.title, "param", "param title is found.");
+ is(tag.name, "foo", "param name is found when desc is missing.");
+ is(tag.desc, "", "param desc is empty when missing.");
+
+ tag = new JSDOC.DocTag("param {object} date A valid date.");
+ is(tag.name, "date", "param name is found with a type.");
+ is(tag.type, "object", "param type is found.");
+ is(tag.desc, "A valid date.", "param desc is found with a type.");
+
+ tag = new JSDOC.DocTag("param aName a description goes\n here.");
+ is(tag.name, "aName", "param name is found without a type.");
+ is(tag.desc, "a description goes\n here.", "param desc is found without a type.");
+
+ tag = new JSDOC.DocTag("param {widget}");
+ is(tag.name, "", "param name is empty when it is not given.");
+
+ tag = new JSDOC.DocTag("param {widget} [foo] This is a description.");
+ is(tag.name, "foo", "optional param name is found.");
+
+ tag = new JSDOC.DocTag("return {aType} This is a description.");
+ is(tag.type, "aType", "when return tag has no name, type is found.");
+ is(tag.desc, "This is a description.", "when return tag has no name, desc is found.");
+
+ tag = new JSDOC.DocTag("author Joe Coder <jcoder@example.com>");
+ is(tag.title, "author", "author tag has a title.");
+ is(tag.type, "", "the author tag has no type.");
+ is(tag.name, "", "the author tag has no name.");
+ is(tag.desc, "Joe Coder <jcoder@example.com>", "author tag has desc.");
+
+ tag = new JSDOC.DocTag("private \t\n ");
+ is(tag.title, "private", "private tag has a title.");
+ is(tag.type, "", "the private tag has no type.");
+ is(tag.name, "", "the private tag has no name.");
+ is(tag.desc, "", "private tag has no desc.");
+
+ tag = new JSDOC.DocTag("example\n example(code);\n more();");
+ is(tag.desc, " example(code);\n more();", "leading whitespace (less one) in examples code is preserved.");
+
+ tag = new JSDOC.DocTag("param theName \n");
+ is(tag.name, "theName", "name only is found.");
+
+ tag = new JSDOC.DocTag("type theDesc \n");
+ is(tag.desc, "theDesc", "desc only is found.");
+
+ tag = new JSDOC.DocTag("type {theType} \n");
+ is(tag.type, "theType", "type only is found.");
+
+ tag = new JSDOC.DocTag("");
+ is(tag.title, "", "title is empty when tag is empty.");
+ */ \ No newline at end of file
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsDoc.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsDoc.js
new file mode 100644
index 0000000..02275a6
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsDoc.js
@@ -0,0 +1,140 @@
+/**
+ @constructor
+ @param [opt] Used to override the commandline options. Useful for testing.
+ @version $Id: JsDoc.js 831 2010-03-09 14:24:56Z micmath $
+*/
+JSDOC.JsDoc = function(/**object*/ opt) {
+ if (opt) {
+ JSDOC.opt = opt;
+ }
+
+ if (JSDOC.opt.h) {
+ JSDOC.usage();
+ quit();
+ }
+
+ // defend against options that are not sane
+ if (JSDOC.opt._.length == 0) {
+ LOG.warn("No source files to work on. Nothing to do.");
+ quit();
+ }
+ if (JSDOC.opt.t === true || JSDOC.opt.d === true) {
+ JSDOC.usage();
+ }
+
+ if (typeof JSDOC.opt.d == "string") {
+ if (!JSDOC.opt.d.charAt(JSDOC.opt.d.length-1).match(/[\\\/]/)) {
+ JSDOC.opt.d = JSDOC.opt.d+"/";
+ }
+ LOG.inform("Output directory set to '"+JSDOC.opt.d+"'.");
+ IO.mkPath(JSDOC.opt.d);
+ }
+ if (JSDOC.opt.e) IO.setEncoding(JSDOC.opt.e);
+
+ // the -r option: scan source directories recursively
+ if (typeof JSDOC.opt.r == "boolean") JSDOC.opt.r = 10;
+ else if (!isNaN(parseInt(JSDOC.opt.r))) JSDOC.opt.r = parseInt(JSDOC.opt.r);
+ else JSDOC.opt.r = 1;
+
+ // the -D option: define user variables
+ var D = {};
+ if (JSDOC.opt.D) {
+ for (var i = 0; i < JSDOC.opt.D.length; i++) {
+ var param = JSDOC.opt.D[i];
+ // remove first and last character if both == "
+ if (
+ param.length > 1
+ && param.charAt(0) == '"'
+ && param.charAt(param.length-1) == '"'
+ ) {
+ param = param.substr(1, param.length-2);
+ }
+ var defineParts = param.split(":");
+ if (defineParts && defineParts.length > 1) {
+ for ( var dpIdx = 2; dpIdx < defineParts.length; dpIdx++ ) {
+ defineParts[1] += ':' + defineParts[dpIdx];
+ }
+ D[defineParts[0]] = defineParts[1];
+ }
+ }
+ }
+ JSDOC.opt.D = D;
+ // combine any conf file D options with the commandline D options
+ if (defined(JSDOC.conf)) for (var c in JSDOC.conf.D) {
+ if (!defined(JSDOC.opt.D[c])) {
+ JSDOC.opt.D[c] = JSDOC.conf.D[c];
+ }
+ }
+
+ // Give plugins a chance to initialize
+ if (defined(JSDOC.PluginManager)) {
+ JSDOC.PluginManager.run("onInit", JSDOC.opt);
+ }
+
+ JSDOC.opt.srcFiles = JSDOC.JsDoc._getSrcFiles();
+ JSDOC.JsDoc._parseSrcFiles();
+ JSDOC.JsDoc.symbolSet = JSDOC.Parser.symbols;
+}
+
+/**
+ Retrieve source file list.
+ @returns {String[]} The pathnames of the files to be parsed.
+ */
+JSDOC.JsDoc._getSrcFiles = function() {
+ JSDOC.JsDoc.srcFiles = [];
+
+ var ext = ["js"];
+ if (JSDOC.opt.x) {
+ ext = JSDOC.opt.x.split(",").map(function($) {return $.toLowerCase()});
+ }
+
+ for (var i = 0; i < JSDOC.opt._.length; i++) {
+ JSDOC.JsDoc.srcFiles = JSDOC.JsDoc.srcFiles.concat(
+ IO.ls(JSDOC.opt._[i], JSDOC.opt.r).filter(
+ function($) {
+ var thisExt = $.split(".").pop().toLowerCase();
+
+ if (JSDOC.opt.E) {
+ for(var n = 0; n < JSDOC.opt.E.length; n++) {
+ if ($.match(new RegExp(JSDOC.opt.E[n]))) {
+ LOG.inform("Excluding " + $);
+ return false; // if the file matches the regex then it's excluded.
+ }
+ }
+ }
+
+ return (ext.indexOf(thisExt) > -1); // we're only interested in files with certain extensions
+ }
+ )
+ );
+ }
+
+ return JSDOC.JsDoc.srcFiles;
+}
+
+JSDOC.JsDoc._parseSrcFiles = function() {
+ JSDOC.Parser.init();
+ for (var i = 0, l = JSDOC.JsDoc.srcFiles.length; i < l; i++) {
+ var srcFile = JSDOC.JsDoc.srcFiles[i];
+
+ if (JSDOC.opt.v) LOG.inform("Parsing file: " + srcFile);
+
+ try {
+ var src = IO.readFile(srcFile);
+ }
+ catch(e) {
+ LOG.warn("Can't read source file '"+srcFile+"': "+e.message);
+ }
+
+ var tr = new JSDOC.TokenReader();
+ var ts = new JSDOC.TokenStream(tr.tokenize(new JSDOC.TextStream(src)));
+
+ JSDOC.Parser.parse(ts, srcFile);
+
+ }
+ JSDOC.Parser.finish();
+
+ if (JSDOC.PluginManager) {
+ JSDOC.PluginManager.run("onFinishedParsing", JSDOC.Parser.symbols);
+ }
+}
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsPlate.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsPlate.js
new file mode 100644
index 0000000..bcaebc9
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/JsPlate.js
@@ -0,0 +1,109 @@
+/**
+ @constructor
+*/
+JSDOC.JsPlate = function(templateFile) {
+ if (templateFile) this.template = IO.readFile(templateFile);
+
+ this.templateFile = templateFile;
+ this.code = "";
+ this.parse();
+}
+
+JSDOC.JsPlate.prototype.parse = function() {
+ this.template = this.template.replace(/\{#[\s\S]+?#\}/gi, "");
+ this.code = "var output=\u001e"+this.template;
+
+ this.code = this.code.replace(
+ /<for +each="(.+?)" +in="(.+?)" *>/gi,
+ function (match, eachName, inName) {
+ return "\u001e;\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+=\u001e";
+ }
+ );
+ this.code = this.code.replace(/<if test="(.+?)">/g, "\u001e;\rif ($1) { output+=\u001e");
+ this.code = this.code.replace(/<elseif test="(.+?)"\s*\/>/g, "\u001e;}\relse if ($1) { output+=\u001e");
+ this.code = this.code.replace(/<else\s*\/>/g, "\u001e;}\relse { output+=\u001e");
+ this.code = this.code.replace(/<\/(if|for)>/g, "\u001e;\r};\routput+=\u001e");
+ this.code = this.code.replace(
+ /\{\+\s*([\s\S]+?)\s*\+\}/gi,
+ function (match, code) {
+ code = code.replace(/"/g, "\u001e"); // prevent qoute-escaping of inline code
+ code = code.replace(/(\r?\n)/g, " ");
+ return "\u001e+ ("+code+") +\u001e";
+ }
+ );
+ this.code = this.code.replace(
+ /\{!\s*([\s\S]+?)\s*!\}/gi,
+ function (match, code) {
+ code = code.replace(/"/g, "\u001e"); // prevent qoute-escaping of inline code
+ code = code.replace(/(\n)/g, " ");
+ return "\u001e; "+code+";\routput+=\u001e";
+ }
+ );
+ this.code = this.code+"\u001e;";
+
+ this.code = this.code.replace(/(\r?\n)/g, "\\n");
+ this.code = this.code.replace(/"/g, "\\\"");
+ this.code = this.code.replace(/\u001e/g, "\"");
+}
+
+JSDOC.JsPlate.prototype.toCode = function() {
+ return this.code;
+}
+
+JSDOC.JsPlate.keys = function(obj) {
+ var keys = [];
+ if (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;
+};
+
+JSDOC.JsPlate.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;
+};
+
+JSDOC.JsPlate.prototype.process = function(data, compact) {
+ var keys = JSDOC.JsPlate.keys;
+ var values = JSDOC.JsPlate.values;
+
+ try {
+ eval(this.code);
+ }
+ catch (e) {
+ print(">> There was an error evaluating the compiled code from template: "+this.templateFile);
+ print(" The error was on line "+e.lineNumber+" "+e.name+": "+e.message);
+ var lines = this.code.split("\r");
+ if (e.lineNumber-2 >= 0) print("line "+(e.lineNumber-1)+": "+lines[e.lineNumber-2]);
+ print("line "+e.lineNumber+": "+lines[e.lineNumber-1]);
+ print("");
+ }
+
+ if (compact) { // patch by mcbain.asm
+ // Remove lines that contain only space-characters, usually left by lines in the template
+ // which originally only contained JSPlate tags or code. This makes it easier to write
+ // non-tricky templates which still put out nice code (not bloated with extra lines).
+ // Lines purposely left blank (just a line ending) are left alone.
+ output = output.replace(/\s+?(\r?)\n/g, "$1\n");
+ }
+
+ /*debug*///print(this.code);
+ return output;
+} \ No newline at end of file
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Lang.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Lang.js
new file mode 100644
index 0000000..62919d7
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Lang.js
@@ -0,0 +1,144 @@
+/**
+ @namespace
+*/
+JSDOC.Lang = {
+}
+
+JSDOC.Lang.isBuiltin = function(name) {
+ return (JSDOC.Lang.isBuiltin.coreObjects.indexOf(name) > -1);
+}
+JSDOC.Lang.isBuiltin.coreObjects = ['_global_', 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', 'RegExp', 'String'];
+
+JSDOC.Lang.whitespace = function(ch) {
+ return JSDOC.Lang.whitespace.names[ch];
+}
+JSDOC.Lang.whitespace.names = {
+ " ": "SPACE",
+ "\f": "FORMFEED",
+ "\t": "TAB",
+ "\u0009": "UNICODE_TAB",
+ "\u000A": "UNICODE_NBR",
+ "\u0008": "VERTICAL_TAB"
+};
+
+JSDOC.Lang.newline = function(ch) {
+ return JSDOC.Lang.newline.names[ch];
+}
+JSDOC.Lang.newline.names = {
+ "\n": "NEWLINE",
+ "\r": "RETURN",
+ "\u000A": "UNICODE_LF",
+ "\u000D": "UNICODE_CR",
+ "\u2029": "UNICODE_PS",
+ "\u2028": "UNICODE_LS"
+};
+
+JSDOC.Lang.keyword = function(word) {
+ return JSDOC.Lang.keyword.names["="+word];
+}
+JSDOC.Lang.keyword.names = {
+ "=break": "BREAK",
+ "=case": "CASE",
+ "=catch": "CATCH",
+ "=const": "VAR",
+ "=continue": "CONTINUE",
+ "=default": "DEFAULT",
+ "=delete": "DELETE",
+ "=do": "DO",
+ "=else": "ELSE",
+ "=false": "FALSE",
+ "=finally": "FINALLY",
+ "=for": "FOR",
+ "=function": "FUNCTION",
+ "=if": "IF",
+ "=in": "IN",
+ "=instanceof": "INSTANCEOF",
+ "=new": "NEW",
+ "=null": "NULL",
+ "=return": "RETURN",
+ "=switch": "SWITCH",
+ "=this": "THIS",
+ "=throw": "THROW",
+ "=true": "TRUE",
+ "=try": "TRY",
+ "=typeof": "TYPEOF",
+ "=void": "VOID",
+ "=while": "WHILE",
+ "=with": "WITH",
+ "=var": "VAR"
+};
+
+JSDOC.Lang.punc = function(ch) {
+ return JSDOC.Lang.punc.names[ch];
+}
+JSDOC.Lang.punc.names = {
+ ";": "SEMICOLON",
+ ",": "COMMA",
+ "?": "HOOK",
+ ":": "COLON",
+ "||": "OR",
+ "&&": "AND",
+ "|": "BITWISE_OR",
+ "^": "BITWISE_XOR",
+ "&": "BITWISE_AND",
+ "===": "STRICT_EQ",
+ "==": "EQ",
+ "=": "ASSIGN",
+ "!==": "STRICT_NE",
+ "!=": "NE",
+ "<<": "LSH",
+ "<=": "LE",
+ "<": "LT",
+ ">>>": "URSH",
+ ">>": "RSH",
+ ">=": "GE",
+ ">": "GT",
+ "++": "INCREMENT",
+ "--": "DECREMENT",
+ "+": "PLUS",
+ "-": "MINUS",
+ "*": "MUL",
+ "/": "DIV",
+ "%": "MOD",
+ "!": "NOT",
+ "~": "BITWISE_NOT",
+ ".": "DOT",
+ "[": "LEFT_BRACKET",
+ "]": "RIGHT_BRACKET",
+ "{": "LEFT_CURLY",
+ "}": "RIGHT_CURLY",
+ "(": "LEFT_PAREN",
+ ")": "RIGHT_PAREN"
+};
+
+JSDOC.Lang.matching = function(name) {
+ return JSDOC.Lang.matching.names[name];
+}
+JSDOC.Lang.matching.names = {
+ "LEFT_PAREN": "RIGHT_PAREN",
+ "RIGHT_PAREN": "LEFT_PAREN",
+ "LEFT_CURLY": "RIGHT_CURLY",
+ "RIGHT_CURLY": "LEFT_CURLY",
+ "LEFT_BRACE": "RIGHT_BRACE",
+ "RIGHT_BRACE": "LEFT_BRACE"
+}
+
+JSDOC.Lang.isNumber = function(str) {
+ return /^(\.[0-9]|[0-9]+\.|[0-9])[0-9]*([eE][+-][0-9]+)?$/i.test(str);
+}
+
+JSDOC.Lang.isHexDec = function(str) {
+ return /^0x[0-9A-F]+$/i.test(str);
+}
+
+JSDOC.Lang.isWordChar = function(str) {
+ return /^[a-zA-Z0-9$_.]+$/.test(str);
+}
+
+JSDOC.Lang.isSpace = function(str) {
+ return (typeof JSDOC.Lang.whitespace(str) != "undefined");
+}
+
+JSDOC.Lang.isNewline = function(str) {
+ return (typeof JSDOC.Lang.newline(str) != "undefined");
+} \ No newline at end of file
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Parser.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Parser.js
new file mode 100644
index 0000000..e489c61
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Parser.js
@@ -0,0 +1,146 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ @namespace
+ @requires JSDOC.Walker
+ @requires JSDOC.Symbol
+ @requires JSDOC.DocComment
+*/
+JSDOC.Parser = {
+ conf: {
+ ignoreCode: JSDOC.opt.n,
+ ignoreAnonymous: true, // factory: true
+ treatUnderscoredAsPrivate: true, // factory: true
+ explain: false // factory: false
+ },
+
+ addSymbol: function(symbol) {
+
+ if (JSDOC.Parser.rename) {
+ for (var n in JSDOC.Parser.rename) {
+ if (symbol.alias.indexOf(n) == 0) {
+ if (symbol.name == symbol.alias) {
+ symbol.name = symbol.name.replace(n, JSDOC.Parser.rename[n]);
+ }
+ symbol.alias = symbol.alias.replace(n, JSDOC.Parser.rename[n]);
+ }
+ }
+ }
+
+ if (JSDOC.opt.S) {
+ if (typeof JSDOC.Parser.secureModules == "undefined") JSDOC.Parser.secureModules = {};
+ if (/^exports\./.test(symbol.alias)) {
+ symbol.srcFile.match(/(^|[\\\/])([^\\\/]+)\.js/i);
+ var fileNS = RegExp.$2;
+
+ // need to create the namespace associated with this file first
+ if (!JSDOC.Parser.secureModules[fileNS]) {
+ JSDOC.Parser.secureModules[fileNS] = 1;
+ var nsSymbol = new JSDOC.Symbol(fileNS, [], "GLOBAL", new JSDOC.DocComment(""));
+ nsSymbol.isNamespace = true;
+ nsSymbol.srcFile = "";
+ nsSymbol.isPrivate = false;
+ nsSymbol.srcFile = symbol.srcFile;
+ nsSymbol.desc = (JSDOC.Parser.symbols.getSymbol(symbol.srcFile) || {desc: ""}).desc;
+ JSDOC.Parser.addSymbol(nsSymbol);
+ }
+
+ symbol.alias = symbol.alias.replace(/^exports\./, fileNS + '.');
+ symbol.name = symbol.name.replace(/^exports\./, '');
+ symbol.memberOf = fileNS;
+ symbol.isStatic = true;
+ }
+ }
+
+ // if a symbol alias is documented more than once the first one with the user docs wins
+ if (JSDOC.Parser.symbols.hasSymbol(symbol.alias)) {
+ var oldSymbol = JSDOC.Parser.symbols.getSymbol(symbol.alias);
+ if (oldSymbol.comment.isUserComment) {
+ if (JSDOC.opt.m) return;
+ if (symbol.comment.isUserComment) { // old and new are both documented
+ LOG.warn("The symbol '"+symbol.alias+"' is documented more than once.");
+ return;
+ }
+ else { // old is documented but new isn't
+ return;
+ }
+ }
+ }
+
+ // we don't document anonymous things
+ if (JSDOC.Parser.conf.ignoreAnonymous && symbol.name.match(/\$anonymous\b/)) return;
+
+ // uderscored things may be treated as if they were marked private, this cascades
+ if (JSDOC.Parser.conf.treatUnderscoredAsPrivate && symbol.name.match(/[.#-]_[^.#-]+$/)) {
+ if (!symbol.comment.getTag("public").length > 0) symbol.isPrivate = true;
+ }
+
+ // -p flag is required to document private things
+ if (!JSDOC.opt.p && symbol.isPrivate) return; // issue #161 fixed by mcbain.asm
+
+ // ignored things are not documented, this doesn't cascade
+ if (symbol.isIgnored) return;
+ JSDOC.Parser.symbols.addSymbol(symbol);
+ },
+
+ addBuiltin: function(name) {
+ var builtin = new JSDOC.Symbol(name, [], "CONSTRUCTOR", new JSDOC.DocComment(""));
+ builtin.isNamespace = true;
+ builtin.srcFile = "";
+ builtin.isPrivate = false;
+ JSDOC.Parser.addSymbol(builtin);
+ return builtin;
+ },
+
+ init: function() {
+ JSDOC.Parser.symbols = new JSDOC.SymbolSet();
+ JSDOC.Parser.walker = new JSDOC.Walker();
+ },
+
+ finish: function() {
+ JSDOC.Parser.symbols.relate();
+
+ // make a litle report about what was found
+ if (JSDOC.Parser.conf.explain) {
+ var symbols = JSDOC.Parser.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+ ", isPrivate => " + symbol.isPrivate);
+ }
+ print("-------------------\n");
+ }
+ }
+}
+
+JSDOC.Parser.parse = function(/**JSDOC.TokenStream*/ts, /**String*/srcFile) {
+ JSDOC.Symbol.srcFile = (srcFile || "");
+ JSDOC.DocComment.shared = ""; // shared comments don't cross file boundaries
+
+ if (!JSDOC.Parser.walker) JSDOC.Parser.init();
+ JSDOC.Parser.walker.walk(ts); // adds to our symbols
+
+ // filter symbols by option
+ for (var p = JSDOC.Parser.symbols._index.first(); p; p = JSDOC.Parser.symbols._index.next()) {
+ var symbol = p.value;
+
+ if (!symbol) continue;
+
+ if (symbol.is("FILE") || symbol.is("GLOBAL")) {
+ continue;
+ }
+ else if (!JSDOC.opt.a && !symbol.comment.isUserComment) {
+ JSDOC.Parser.symbols.deleteSymbol(symbol.alias);
+ }
+
+ if (/#$/.test(symbol.alias)) { // we don't document prototypes
+ JSDOC.Parser.symbols.deleteSymbol(symbol.alias);
+ }
+ }
+
+ return JSDOC.Parser.symbols.toArray();
+}
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/PluginManager.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/PluginManager.js
new file mode 100644
index 0000000..9c91193
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/PluginManager.js
@@ -0,0 +1,33 @@
+/**
+ @namespace Holds functionality related to running plugins.
+*/
+JSDOC.PluginManager = {
+}
+
+/**
+ @param name A unique name that identifies that plugin.
+ @param handlers A collection of named functions. The names correspond to hooks in the core code.
+*/
+JSDOC.PluginManager.registerPlugin = function(/**String*/name, /**Object*/handlers) {
+ if (!defined(JSDOC.PluginManager.plugins))
+ /** The collection of all plugins. Requires a unique name for each.
+ */
+ JSDOC.PluginManager.plugins = {};
+
+
+ JSDOC.PluginManager.plugins[name] = handlers;
+}
+
+/**
+ @param hook The name of the hook that is being caught.
+ @param target Any object. This will be passed as the only argument to the handler whose
+ name matches the hook name. Handlers cannot return a value, so must modify the target
+ object to have an effect.
+*/
+JSDOC.PluginManager.run = function(/**String*/hook, /**Mixed*/target) {
+ for (var name in JSDOC.PluginManager.plugins) {
+ if (defined(JSDOC.PluginManager.plugins[name][hook])) {
+ JSDOC.PluginManager.plugins[name][hook](target);
+ }
+ }
+}
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Symbol.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Symbol.js
new file mode 100644
index 0000000..1aa44da
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Symbol.js
@@ -0,0 +1,644 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ Create a new Symbol.
+ @class Represents a symbol in the source code.
+ */
+JSDOC.Symbol = function() {
+ this.init();
+ if (arguments.length) this.populate.apply(this, arguments);
+}
+
+JSDOC.Symbol.count = 0;
+
+JSDOC.Symbol.prototype.init = function() {
+ this._name = "";
+ this._params = [];
+ this.$args = [];
+ this.addOn = "";
+ this.alias = "";
+ this.augments = [];
+ this.author = "";
+ this.classDesc = "";
+ this.comment = {};
+ this.defaultValue = undefined;
+ this.deprecated = "";
+ this.desc = "";
+ this.example = [];
+ this.exceptions = [];
+ this.fires = [];
+ this.id = JSDOC.Symbol.count++;
+ this.inherits = [];
+ this.inheritsFrom = [];
+ this.isa = "OBJECT";
+ this.isConstant = false;
+ this.isEvent = false;
+ this.isIgnored = false;
+ this.isInner = false;
+ this.isNamespace = false;
+ this.isPrivate = false;
+ this.isStatic = false;
+ this.memberOf = "";
+ this.methods = [];
+ this.properties = [];
+ this.requires = [];
+ this.returns = [];
+ this.see = [];
+ this.since = "";
+ this.srcFile = {};
+ this.type = "";
+ this.version = "";
+}
+
+JSDOC.Symbol.prototype.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]+" => "+Dumper.dump(this[keys[i]])+",\n";
+ }
+ return "\n{\n" + out + "}\n";
+}
+
+JSDOC.Symbol.prototype.clone = function() {
+ var clone = new JSDOC.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;
+}
+
+JSDOC.Symbol.prototype.__defineSetter__("name",
+ function(n) { n = n.replace(/^_global_[.#-]/, ""); n = n.replace(/\.prototype\.?/g, '#'); this._name = n; }
+);
+JSDOC.Symbol.prototype.__defineGetter__("name",
+ function() { return this._name; }
+);
+JSDOC.Symbol.prototype.__defineSetter__("params",
+ function(v) {
+ for (var i = 0, l = v.length; i < l; i++) {
+ if (v[i].constructor != JSDOC.DocTag) { // may be a generic object parsed from signature, like {type:..., name:...}
+ this._params[i] = new JSDOC.DocTag("param"+((v[i].type)?" {"+v[i].type+"}":"")+" "+v[i].name);
+ }
+ else {
+ this._params[i] = v[i];
+ }
+ }
+ }
+);
+JSDOC.Symbol.prototype.__defineGetter__("params",
+ function() { return this._params; }
+);
+
+JSDOC.Symbol.prototype.getEvents = function() {
+ var events = [];
+ for (var i = 0, l = this.methods.length; i < l; i++) {
+ if (this.methods[i].isEvent) {
+ this.methods[i].name = this.methods[i].name.replace("event:", "");
+ events.push(this.methods[i]);
+ }
+ }
+ return events;
+}
+
+JSDOC.Symbol.prototype.getMethods = function() {
+ var nonEvents = [];
+ for (var i = 0, l = this.methods.length; i < l; i++) {
+ if (!this.methods[i].isEvent) {
+ nonEvents.push(this.methods[i]);
+ }
+ }
+ return nonEvents;
+}
+
+
+JSDOC.Symbol.prototype.populate = function(
+ /** String */ name,
+ /** Object[] */ params,
+ /** String */ isa,
+ /** JSDOC.DocComment */ comment
+) {
+ this.$args = arguments;
+
+ this.name = name;
+ this.alias = this.name;
+
+ this.params = params;
+ this.isa = (isa == "VIRTUAL")? "OBJECT":isa;
+ this.comment = comment || new JSDOC.DocComment("");
+ this.srcFile = JSDOC.Symbol.srcFile;
+
+ if (this.is("FILE") && !this.alias) this.alias = this.srcFile;
+
+ this.setTags();
+
+ if (typeof JSDOC.PluginManager != "undefined") {
+ JSDOC.PluginManager.run("onSymbol", this);
+ }
+}
+
+JSDOC.Symbol.prototype.setTags = function() {
+ // @author
+ var authors = this.comment.getTag("author");
+ if (authors.length) {
+ this.author = authors.map(function($){return $.desc;}).join(", ");
+ }
+
+ /*t:
+ plan(34, "testing JSDOC.Symbol");
+
+ requires("../lib/JSDOC/DocComment.js");
+ requires("../frame/String.js");
+ requires("../lib/JSDOC/DocTag.js");
+
+ var sym = new JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@author Joe Smith*"+"/"));
+ is(sym.author, "Joe Smith", "@author tag, author is found.");
+ */
+
+ // @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 JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@desc This is a description.*"+"/"));
+ is(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 JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@overview This is an overview.*"+"/"));
+ is(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 JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@since 1.01*"+"/"));
+ is(sym.since, "1.01", "@since tag, description is found.");
+ */
+
+ // @constant
+ if (this.comment.getTag("constant").length) {
+ this.isConstant = true;
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@constant*"+"/"));
+ is(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 JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@version 2.0x*"+"/"));
+ is(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 JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@deprecated Use other method.*"+"/"));
+ is(sym.deprecated, "Use other method.", "@deprecated tag, desc is found.");
+ */
+
+ // @example
+ var examples = this.comment.getTag("example");
+ if (examples.length) {
+ this.example = examples.map(
+ // trim trailing whitespace
+ function($) {
+ $.desc = $.desc.replace(/\s+$/, "");
+ return $;
+ }
+ );
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@example This\n is an example. \n*"+"/"));
+ isnt(typeof sym.example[0], "undefined", "@example tag, creates sym.example array.");
+ is(sym.example[0], "This\n is an example.", "@example 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 JSDOC.Symbol("foo", [], "FILE", new JSDOC.DocComment("/**@see The other thing.*"+"/"));
+ is(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.
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@class This describes the class.*"+"/"));
+ is(sym.isa, "CONSTRUCTOR", "@class tag, makes symbol a constructor.");
+ is(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;
+ this.isNamespace = true;
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@namespace This describes the namespace.*"+"/"));
+ is(sym.classDesc, "This describes the namespace.", "@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.params;
+
+ if (thisParams.length == 0) { // none exist yet, so just bung all these user-defined params straight in
+ this.params = 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 JSDOC.Symbol("foo", [{type: "array", name: "pages"}], "FUNCTION", new JSDOC.DocComment("/**Description.*"+"/"));
+ is(sym.params.length, 1, "parser defined param is found.");
+
+ sym = new JSDOC.Symbol("foo", [], "FUNCTION", new JSDOC.DocComment("/**Description.\n@param {array} pages*"+"/"));
+ is(sym.params.length, 1, "user defined param is found.");
+ is(sym.params[0].type, "array", "user defined param type is found.");
+ is(sym.params[0].name, "pages", "user defined param name is found.");
+
+ sym = new JSDOC.Symbol("foo", [{type: "array", name: "pages"}], "FUNCTION", new JSDOC.DocComment("/**Description.\n@param {string} uid*"+"/"));
+ is(sym.params.length, 1, "user defined param overwrites parser defined param.");
+ is(sym.params[0].type, "string", "user defined param type overwrites parser defined param type.");
+ is(sym.params[0].name, "uid", "user defined param name overwrites parser defined param name.");
+
+ sym = new JSDOC.Symbol("foo", [{type: "array", name: "pages"}, {type: "number", name: "count"}], "FUNCTION", new JSDOC.DocComment("/**Description.\n@param {string} uid*"+"/"));
+ is(sym.params.length, 2, "user defined params overlay parser defined params.");
+ is(sym.params[1].type, "number", "user defined param type overlays parser defined param type.");
+ is(sym.params[1].name, "count", "user defined param name overlays parser defined param name.");
+
+ sym = new JSDOC.Symbol("foo", [], "FUNCTION", new JSDOC.DocComment("/**Description.\n@param {array} pages The pages description.*"+"/"));
+ is(sym.params.length, 1, "user defined param with description is found.");
+ is(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 JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@constructor*"+"/"));
+ is(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;
+ }
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@static\n@constructor*"+"/"));
+ is(sym.isStatic, true, "@static tag, makes isStatic true.");
+ is(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 JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@inner*"+"/"));
+ is(sym.isStatic, false, "@inner tag, makes isStatic false.");
+ is(sym.isInner, true, "@inner makes isInner true.");
+ */
+
+ // @name
+ var names = this.comment.getTag("name");
+ if (names.length) {
+ this.name = names[0].desc;
+ }
+
+ /*t:
+ // todo
+ */
+
+ // @field
+ if (this.comment.getTag("field").length) {
+ this.isa = "OBJECT";
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "FUNCTION", new JSDOC.DocComment("/**@field*"+"/"));
+ is(sym.isa, "OBJECT", "@field tag, makes symbol an object.");
+ */
+
+ // @function
+ if (this.comment.getTag("function").length) {
+ this.isa = "FUNCTION";
+ if (/event:/.test(this.alias)) this.isEvent = true;
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@function*"+"/"));
+ is(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;
+ if (!/event:/.test(this.alias))
+ this.alias = this.alias.replace(/^(.*[.#-])([^.#-]+)$/, "$1event:$2");
+ }
+
+ /*t:
+ var sym = new JSDOC.Symbol("foo", [], "OBJECT", new JSDOC.DocComment("/**@event*"+"/"));
+ is(sym.isa, "FUNCTION", "@event tag, makes symbol a function.");
+ is(sym.isEvent, true, "@event makes isEvent true.");
+ */
+
+ // @fires
+ var fires = this.comment.getTag("fires");
+ if (fires.length) {
+ for (var i = 0; i < fires.length; i++) {
+ this.fires.push(fires[i].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 JSDOC.Symbol(this.alias+"#"+properties[i].name, [], "OBJECT", new JSDOC.DocComment("/**"+properties[i].desc+"*/"));
+ // TODO: shouldn't the following happen in the addProperty method of Symbol?
+ if (properties[i].type) property.type = properties[i].type;
+ if (properties[i].defaultValue) property.defaultValue = properties[i].defaultValue;
+ this.addProperty(property);
+ if (!JSDOC.Parser.symbols.getSymbolByName(property.name))
+ JSDOC.Parser.addSymbol(property);
+ }
+ }
+
+ /*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");
+
+ // @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, "#");
+ }
+
+ /*t:
+ // todo
+ */
+
+ // @public
+ if (this.comment.getTag("public").length) {
+ this.isPrivate = false;
+ }
+
+ /*t:
+ // todo
+ */
+
+ if (JSDOC.PluginManager) {
+ JSDOC.PluginManager.run("onSetTags", this);
+ }
+}
+
+JSDOC.Symbol.prototype.is = function(what) {
+ return this.isa === what;
+}
+
+JSDOC.Symbol.prototype.isBuiltin = function() {
+ return JSDOC.Lang.isBuiltin(this.alias);
+}
+
+JSDOC.Symbol.prototype.setType = function(/**String*/comment, /**Boolean*/overwrite) {
+ if (!overwrite && this.type) return;
+ var typeComment = JSDOC.DocComment.unwrapComment(comment);
+ this.type = typeComment;
+}
+
+JSDOC.Symbol.prototype.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);
+ }
+}
+
+JSDOC.Symbol.prototype.hasMember = function(name) {
+ return (this.hasMethod(name) || this.hasProperty(name));
+}
+
+JSDOC.Symbol.prototype.addMember = function(symbol) {
+ if (symbol.is("FUNCTION")) { this.addMethod(symbol); }
+ else if (symbol.is("OBJECT")) { this.addProperty(symbol); }
+}
+
+JSDOC.Symbol.prototype.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;
+}
+
+JSDOC.Symbol.prototype.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
+}
+
+JSDOC.Symbol.prototype.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;
+}
+
+JSDOC.Symbol.prototype.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
+}
+
+JSDOC.Symbol.srcFile = ""; //running reference to the current file being parsed
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/SymbolSet.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/SymbolSet.js
new file mode 100644
index 0000000..8e3a2eb
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/SymbolSet.js
@@ -0,0 +1,243 @@
+/** @constructor */
+JSDOC.SymbolSet = function() {
+ this.init();
+}
+
+JSDOC.SymbolSet.prototype.init = function() {
+ this._index = new Hash();
+}
+
+JSDOC.SymbolSet.prototype.keys = function() {
+ return this._index.keys();
+}
+
+JSDOC.SymbolSet.prototype.hasSymbol = function(alias) {
+ return this._index.hasKey(alias);
+}
+
+JSDOC.SymbolSet.prototype.addSymbol = function(symbol) {
+ if (JSDOC.opt.a && this.hasSymbol(symbol.alias)) {
+ LOG.warn("Overwriting symbol documentation for: " + symbol.alias + ".");
+ this.deleteSymbol(symbol.alias);
+ }
+ this._index.set(symbol.alias, symbol);
+}
+
+JSDOC.SymbolSet.prototype.getSymbol = function(alias) {
+ if (this.hasSymbol(alias)) return this._index.get(alias);
+}
+
+JSDOC.SymbolSet.prototype.getSymbolByName = function(name) {
+ for (var p = this._index.first(); p; p = this._index.next()) {
+ var symbol = p.value;
+ if (symbol.name == name) return symbol;
+ }
+}
+
+JSDOC.SymbolSet.prototype.toArray = function() {
+ return this._index.values();
+}
+
+JSDOC.SymbolSet.prototype.deleteSymbol = function(alias) {
+ if (!this.hasSymbol(alias)) return;
+ this._index.drop(alias);
+}
+
+JSDOC.SymbolSet.prototype.renameSymbol = function(oldName, newName) {
+ // todo: should check if oldname or newname already exist
+ this._index.replace(oldName, newName);
+ this._index.get(newName).alias = newName;
+ return newName;
+}
+
+JSDOC.SymbolSet.prototype.relate = function() {
+ this.resolveBorrows();
+ this.resolveMemberOf();
+ this.resolveAugments();
+}
+
+JSDOC.SymbolSet.prototype.resolveBorrows = function() {
+ for (var p = this._index.first(); p; p = this._index.next()) {
+ var symbol = p.value;
+ if (symbol.is("FILE") || symbol.is("GLOBAL")) continue;
+
+ var borrows = symbol.inherits;
+ for (var i = 0; i < borrows.length; i++) {
+
+if (/#$/.test(borrows[i].alias)) {
+ LOG.warn("Attempted to borrow entire instance of "+borrows[i].alias+" but that feature is not yet implemented.");
+ return;
+}
+ var borrowed = this.getSymbol(borrows[i].alias);
+
+ if (!borrowed) {
+ LOG.warn("Can't borrow undocumented "+borrows[i].alias+".");
+ continue;
+ }
+
+ if (borrows[i].as == borrowed.alias) {
+ var assumedName = borrowed.name.split(/([#.-])/).pop();
+ borrows[i].as = symbol.name+RegExp.$1+assumedName;
+ LOG.inform("Assuming borrowed as name is "+borrows[i].as+" but that feature is experimental.");
+ }
+
+ var borrowAsName = borrows[i].as;
+ var borrowAsAlias = borrowAsName;
+ if (!borrowAsName) {
+ 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);
+ }
+ }
+}
+
+JSDOC.SymbolSet.prototype.resolveMemberOf = function() {
+ for (var p = this._index.first(); p; p = this._index.next()) {
+ var symbol = p.value;
+
+ if (symbol.is("FILE") || symbol.is("GLOBAL")) continue;
+
+ // the memberOf value was provided in the @memberOf tag
+ else if (symbol.memberOf) {
+ // like foo.bar is a memberOf foo
+ if (symbol.alias.indexOf(symbol.memberOf) == 0) {
+ var memberMatch = new RegExp("^("+symbol.memberOf+")[.#-]?(.+)$");
+ var aliasParts = symbol.alias.match(memberMatch);
+
+ if (aliasParts) {
+ symbol.memberOf = aliasParts[1];
+ symbol.name = aliasParts[2];
+ }
+
+ var nameParts = symbol.name.match(memberMatch);
+
+ if (nameParts) {
+ symbol.name = nameParts[2];
+ }
+ }
+ // like bar is a memberOf foo
+ else {
+ var joiner = symbol.memberOf.charAt(symbol.memberOf.length-1);
+ if (!/[.#-]/.test(joiner)) symbol.memberOf += ".";
+ this.renameSymbol(symbol.alias, 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;
+ default: // memberOf ends in none of the above
+ symbol.isStatic = 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);
+ }
+ // add to parent's methods or properties list
+ if (symbol.memberOf) {
+
+ var container = this.getSymbol(symbol.memberOf);
+ if (!container) {
+ if (JSDOC.Lang.isBuiltin(symbol.memberOf)) container = JSDOC.Parser.addBuiltin(symbol.memberOf);
+ else {
+ LOG.warn("Trying to document "+symbol.name +" as a member of undocumented symbol "+symbol.memberOf+".");
+ }
+ }
+
+ if (container) container.addMember(symbol);
+ }
+ }
+}
+
+JSDOC.SymbolSet.prototype.resolveAugments = function() {
+ for (var p = this._index.first(); p; p = this._index.next()) {
+ var symbol = p.value;
+
+ if (symbol.alias == "_global_" || symbol.is("FILE")) continue;
+ JSDOC.SymbolSet.prototype.walk.apply(this, [symbol]);
+ }
+}
+
+JSDOC.SymbolSet.prototype.walk = function(symbol) {
+ var augments = symbol.augments;
+ for(var i = 0; i < augments.length; i++) {
+ var contributer = this.getSymbol(augments[i]);
+ if (!contributer && JSDOC.Lang.isBuiltin(''+augments[i])) {
+ contributer = new JSDOC.Symbol("_global_."+augments[i], [], augments[i], new JSDOC.DocComment("Built in."));
+ contributer.isNamespace = true;
+ contributer.srcFile = "";
+ contributer.isPrivate = false;
+ JSDOC.Parser.addSymbol(contributer);
+ }
+
+ if (contributer) {
+ if (contributer.augments.length) {
+ JSDOC.SymbolSet.prototype.walk.apply(this, [contributer]);
+ }
+
+ symbol.inheritsFrom.push(contributer.alias);
+ //if (!isUnique(symbol.inheritsFrom)) {
+ // 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;
+
+ for (var ci = 0, cl = cmethods.length; ci < cl; ci++) {
+ if (!cmethods[ci].isStatic) symbol.inherit(cmethods[ci]);
+ }
+ for (var ci = 0, cl = cproperties.length; ci < cl; ci++) {
+ if (!cproperties[ci].isStatic) symbol.inherit(cproperties[ci]);
+ }
+ //}
+ }
+ else LOG.warn("Can't augment contributer: "+augments[i]+", not found.");
+ }
+}
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TextStream.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TextStream.js
new file mode 100644
index 0000000..ccc48a8
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TextStream.js
@@ -0,0 +1,41 @@
+
+/**
+ @constructor
+*/
+JSDOC.TextStream = function(text) {
+ if (typeof(text) == "undefined") text = "";
+ text = ""+text;
+ this.text = text;
+ this.cursor = 0;
+}
+
+JSDOC.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);
+}
+
+JSDOC.TextStream.prototype.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
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Token.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Token.js
new file mode 100644
index 0000000..fb7f9d9
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Token.js
@@ -0,0 +1,18 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ @constructor
+*/
+JSDOC.Token = function(data, type, name) {
+ this.data = data;
+ this.type = type;
+ this.name = name;
+}
+
+JSDOC.Token.prototype.toString = function() {
+ return "<"+this.type+" name=\""+this.name+"\">"+this.data+"</"+this.type+">";
+}
+
+JSDOC.Token.prototype.is = function(what) {
+ return this.name === what || this.type === what;
+} \ No newline at end of file
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenReader.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenReader.js
new file mode 100644
index 0000000..9f658fb
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenReader.js
@@ -0,0 +1,332 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ @class Search a {@link JSDOC.TextStream} for language tokens.
+*/
+JSDOC.TokenReader = function() {
+ this.keepDocs = true;
+ this.keepWhite = false;
+ this.keepComments = false;
+}
+
+/**
+ @type {JSDOC.Token[]}
+ */
+JSDOC.TokenReader.prototype.tokenize = function(/**JSDOC.TextStream*/stream) {
+ var tokens = [];
+ /**@ignore*/ tokens.last = function() { return tokens[tokens.length-1]; }
+ /**@ignore*/ tokens.lastSym = function() {
+ for (var i = tokens.length-1; i >= 0; i--) {
+ if (!(tokens[i].is("WHIT") || tokens[i].is("COMM"))) return tokens[i];
+ }
+ }
+
+ while (!stream.look().eof) {
+ if (this.read_mlcomment(stream, tokens)) continue;
+ if (this.read_slcomment(stream, tokens)) continue;
+ if (this.read_dbquote(stream, tokens)) continue;
+ if (this.read_snquote(stream, tokens)) continue;
+ if (this.read_regx(stream, tokens)) continue;
+ if (this.read_numb(stream, tokens)) continue;
+ if (this.read_punc(stream, tokens)) continue;
+ if (this.read_newline(stream, tokens)) continue;
+ if (this.read_space(stream, tokens)) continue;
+ if (this.read_word(stream, tokens)) continue;
+
+ // if execution reaches here then an error has happened
+ tokens.push(new JSDOC.Token(stream.next(), "TOKN", "UNKNOWN_TOKEN"));
+ }
+ return tokens;
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_word = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var found = "";
+ while (!stream.look().eof && JSDOC.Lang.isWordChar(stream.look())) {
+ found += stream.next();
+ }
+
+ if (found === "") {
+ return false;
+ }
+ else {
+ var name;
+ if ((name = JSDOC.Lang.keyword(found))) tokens.push(new JSDOC.Token(found, "KEYW", name));
+ else tokens.push(new JSDOC.Token(found, "NAME", "NAME"));
+ return true;
+ }
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_punc = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var found = "";
+ var name;
+ while (!stream.look().eof && JSDOC.Lang.punc(found+stream.look())) {
+ found += stream.next();
+ }
+
+ if (found === "") {
+ return false;
+ }
+ else {
+ tokens.push(new JSDOC.Token(found, "PUNC", JSDOC.Lang.punc(found)));
+ return true;
+ }
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_space = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var found = "";
+
+ while (!stream.look().eof && JSDOC.Lang.isSpace(stream.look())) {
+ found += stream.next();
+ }
+
+ if (found === "") {
+ return false;
+ }
+ else {
+ if (this.collapseWhite) found = " ";
+ if (this.keepWhite) tokens.push(new JSDOC.Token(found, "WHIT", "SPACE"));
+ return true;
+ }
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_newline = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var found = "";
+
+ while (!stream.look().eof && JSDOC.Lang.isNewline(stream.look())) {
+ found += stream.next();
+ }
+
+ if (found === "") {
+ return false;
+ }
+ else {
+ if (this.collapseWhite) found = "\n";
+ if (this.keepWhite) tokens.push(new JSDOC.Token(found, "WHIT", "NEWLINE"));
+ return true;
+ }
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_mlcomment = function(/**JSDOC.TokenStream*/stream, tokens) {
+ if (stream.look() == "/" && stream.look(1) == "*") {
+ var found = stream.next(2);
+
+ while (!stream.look().eof && !(stream.look(-1) == "/" && stream.look(-2) == "*")) {
+ found += stream.next();
+ }
+
+ // to start doclet we allow /** or /*** but not /**/ or /****
+ if (/^\/\*\*([^\/]|\*[^*])/.test(found) && this.keepDocs) tokens.push(new JSDOC.Token(found, "COMM", "JSDOC"));
+ else if (this.keepComments) tokens.push(new JSDOC.Token(found, "COMM", "MULTI_LINE_COMM"));
+ return true;
+ }
+ return false;
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_slcomment = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var found;
+ if (
+ (stream.look() == "/" && stream.look(1) == "/" && (found=stream.next(2)))
+ ||
+ (stream.look() == "<" && stream.look(1) == "!" && stream.look(2) == "-" && stream.look(3) == "-" && (found=stream.next(4)))
+ ) {
+
+ while (!stream.look().eof && !JSDOC.Lang.isNewline(stream.look())) {
+ found += stream.next();
+ }
+
+ if (this.keepComments) {
+ tokens.push(new JSDOC.Token(found, "COMM", "SINGLE_LINE_COMM"));
+ }
+ return true;
+ }
+ return false;
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_dbquote = function(/**JSDOC.TokenStream*/stream, tokens) {
+ if (stream.look() == "\"") {
+ // find terminator
+ var string = stream.next();
+
+ while (!stream.look().eof) {
+ if (stream.look() == "\\") {
+ if (JSDOC.Lang.isNewline(stream.look(1))) {
+ do {
+ stream.next();
+ } while (!stream.look().eof && JSDOC.Lang.isNewline(stream.look()));
+ string += "\\\n";
+ }
+ else {
+ string += stream.next(2);
+ }
+ }
+ else if (stream.look() == "\"") {
+ string += stream.next();
+ tokens.push(new JSDOC.Token(string, "STRN", "DOUBLE_QUOTE"));
+ return true;
+ }
+ else {
+ string += stream.next();
+ }
+ }
+ }
+ return false; // error! unterminated string
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_snquote = function(/**JSDOC.TokenStream*/stream, tokens) {
+ if (stream.look() == "'") {
+ // find terminator
+ var string = stream.next();
+
+ while (!stream.look().eof) {
+ if (stream.look() == "\\") { // escape sequence
+ string += stream.next(2);
+ }
+ else if (stream.look() == "'") {
+ string += stream.next();
+ tokens.push(new JSDOC.Token(string, "STRN", "SINGLE_QUOTE"));
+ return true;
+ }
+ else {
+ string += stream.next();
+ }
+ }
+ }
+ return false; // error! unterminated string
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_numb = function(/**JSDOC.TokenStream*/stream, tokens) {
+ if (stream.look() === "0" && stream.look(1) == "x") {
+ return this.read_hex(stream, tokens);
+ }
+
+ var found = "";
+
+ while (!stream.look().eof && JSDOC.Lang.isNumber(found+stream.look())){
+ found += stream.next();
+ }
+
+ if (found === "") {
+ return false;
+ }
+ else {
+ if (/^0[0-7]/.test(found)) tokens.push(new JSDOC.Token(found, "NUMB", "OCTAL"));
+ else tokens.push(new JSDOC.Token(found, "NUMB", "DECIMAL"));
+ return true;
+ }
+}
+/*t:
+ requires("../lib/JSDOC/TextStream.js");
+ requires("../lib/JSDOC/Token.js");
+ requires("../lib/JSDOC/Lang.js");
+
+ plan(3, "testing JSDOC.TokenReader.prototype.read_numb");
+
+ //// setup
+ var src = "function foo(num){while (num+8.0 >= 0x20 && num < 0777){}}";
+ var tr = new JSDOC.TokenReader();
+ var tokens = tr.tokenize(new JSDOC.TextStream(src));
+
+ var hexToken, octToken, decToken;
+ for (var i = 0; i < tokens.length; i++) {
+ if (tokens[i].name == "HEX_DEC") hexToken = tokens[i];
+ if (tokens[i].name == "OCTAL") octToken = tokens[i];
+ if (tokens[i].name == "DECIMAL") decToken = tokens[i];
+ }
+ ////
+
+ is(decToken.data, "8.0", "decimal number is found in source.");
+ is(hexToken.data, "0x20", "hexdec number is found in source (issue #99).");
+ is(octToken.data, "0777", "octal number is found in source.");
+*/
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_hex = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var found = stream.next(2);
+
+ while (!stream.look().eof) {
+ if (JSDOC.Lang.isHexDec(found) && !JSDOC.Lang.isHexDec(found+stream.look())) { // done
+ tokens.push(new JSDOC.Token(found, "NUMB", "HEX_DEC"));
+ return true;
+ }
+ else {
+ found += stream.next();
+ }
+ }
+ return false;
+}
+
+/**
+ @returns {Boolean} Was the token found?
+ */
+JSDOC.TokenReader.prototype.read_regx = function(/**JSDOC.TokenStream*/stream, tokens) {
+ var last;
+ if (
+ stream.look() == "/"
+ &&
+ (
+
+ (
+ !(last = tokens.lastSym()) // there is no last, the regex is the first symbol
+ ||
+ (
+ !last.is("NUMB")
+ && !last.is("NAME")
+ && !last.is("RIGHT_PAREN")
+ && !last.is("RIGHT_BRACKET")
+ )
+ )
+ )
+ ) {
+ var regex = stream.next();
+
+ while (!stream.look().eof) {
+ if (stream.look() == "\\") { // escape sequence
+ regex += stream.next(2);
+ }
+ else if (stream.look() == "/") {
+ regex += stream.next();
+
+ while (/[gmi]/.test(stream.look())) {
+ regex += stream.next();
+ }
+
+ tokens.push(new JSDOC.Token(regex, "REGX", "REGX"));
+ return true;
+ }
+ else {
+ regex += stream.next();
+ }
+ }
+ // error: unterminated regex
+ }
+ return false;
+}
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenStream.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenStream.js
new file mode 100644
index 0000000..1eeb44c
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/TokenStream.js
@@ -0,0 +1,133 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/**
+ @constructor
+*/
+JSDOC.TokenStream = function(tokens) {
+ this.tokens = (tokens || []);
+ this.rewind();
+}
+
+/**
+ @constructor
+ @private
+*/
+function VoidToken(/**String*/type) {
+ this.toString = function() {return "<VOID type=\""+type+"\">"};
+ this.is = function(){return false;}
+}
+
+JSDOC.TokenStream.prototype.rewind = function() {
+ this.cursor = -1;
+}
+
+/**
+ @type JSDOC.Token
+*/
+JSDOC.TokenStream.prototype.look = function(/**Number*/n, /**Boolean*/considerWhitespace) {
+ if (typeof n == "undefined") n = 0;
+
+ if (considerWhitespace == true) {
+ if (this.cursor+n < 0 || this.cursor+n > this.tokens.length) return {};
+ return this.tokens[this.cursor+n];
+ }
+ else {
+ var count = 0;
+ var i = this.cursor;
+
+ while (true) {
+ if (i < 0) return new JSDOC.Token("", "VOID", "START_OF_STREAM");
+ else if (i > this.tokens.length) return new JSDOC.Token("", "VOID", "END_OF_STREAM");
+
+ if (i != this.cursor && (this.tokens[i] === undefined || this.tokens[i].is("WHIT"))) {
+ if (n < 0) i--; else i++;
+ continue;
+ }
+
+ if (count == Math.abs(n)) {
+ return this.tokens[i];
+ }
+ count++;
+ (n < 0)? i-- : i++;
+ }
+
+ return new JSDOC.Token("", "VOID", "STREAM_ERROR"); // because null isn't an object and caller always expects an object
+ }
+}
+
+/**
+ @type JSDOC.Token|JSDOC.Token[]
+*/
+JSDOC.TokenStream.prototype.next = function(/**Number*/howMany) {
+ if (typeof howMany == "undefined") howMany = 1;
+ if (howMany < 1) return null;
+ var got = [];
+
+ for (var i = 1; i <= howMany; i++) {
+ if (this.cursor+i >= this.tokens.length) {
+ return null;
+ }
+ got.push(this.tokens[this.cursor+i]);
+ }
+ this.cursor += howMany;
+
+ if (howMany == 1) {
+ return got[0];
+ }
+ else return got;
+}
+
+/**
+ @type JSDOC.Token[]
+*/
+JSDOC.TokenStream.prototype.balance = function(/**String*/start, /**String*/stop) {
+ if (!stop) stop = JSDOC.Lang.matching(start);
+
+ var depth = 0;
+ var got = [];
+ var started = false;
+
+ while ((token = this.look())) {
+ if (token.is(start)) {
+ depth++;
+ started = true;
+ }
+
+ if (started) {
+ got.push(token);
+ }
+
+ if (token.is(stop)) {
+ depth--;
+ if (depth == 0) return got;
+ }
+ if (!this.next()) break;
+ }
+}
+
+JSDOC.TokenStream.prototype.getMatchingToken = function(/**String*/start, /**String*/stop) {
+ var depth = 0;
+ var cursor = this.cursor;
+
+ if (!start) {
+ start = JSDOC.Lang.matching(stop);
+ depth = 1;
+ }
+ if (!stop) stop = JSDOC.Lang.matching(start);
+
+ while ((token = this.tokens[cursor])) {
+ if (token.is(start)) {
+ depth++;
+ }
+
+ if (token.is(stop) && cursor) {
+ depth--;
+ if (depth == 0) return this.tokens[cursor];
+ }
+ cursor++;
+ }
+}
+
+JSDOC.TokenStream.prototype.insertAhead = function(/**JSDOC.Token*/token) {
+ this.tokens.splice(this.cursor+1, 0, token);
+} \ No newline at end of file
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Util.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Util.js
new file mode 100644
index 0000000..6d7edb3
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Util.js
@@ -0,0 +1,32 @@
+/**
+ * @namespace
+ * @deprecated Use {@link FilePath} instead.
+ */
+JSDOC.Util = {
+}
+
+/**
+ * @deprecated Use {@link FilePath.fileName} instead.
+ */
+JSDOC.Util.fileName = function(path) {
+ LOG.warn("JSDOC.Util.fileName is deprecated. Use FilePath.fileName instead.");
+ var nameStart = Math.max(path.lastIndexOf("/")+1, path.lastIndexOf("\\")+1, 0);
+ return path.substring(nameStart);
+}
+
+/**
+ * @deprecated Use {@link FilePath.fileExtension} instead.
+ */
+JSDOC.Util.fileExtension = function(filename) {
+ LOG.warn("JSDOC.Util.fileExtension is deprecated. Use FilePath.fileExtension instead.");
+ return filename.split(".").pop().toLowerCase();
+};
+
+/**
+ * @deprecated Use {@link FilePath.dir} instead.
+ */
+JSDOC.Util.dir = function(path) {
+ LOG.warn("JSDOC.Util.dir is deprecated. Use FilePath.dir instead.");
+ var nameStart = Math.max(path.lastIndexOf("/")+1, path.lastIndexOf("\\")+1, 0);
+ return path.substring(0, nameStart-1);
+}
diff --git a/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Walker.js b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Walker.js
new file mode 100644
index 0000000..6ecaea8
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/lib/JSDOC/Walker.js
@@ -0,0 +1,507 @@
+if (typeof JSDOC == "undefined") JSDOC = {};
+
+/** @constructor */
+JSDOC.Walker = function(/**JSDOC.TokenStream*/ts) {
+ this.init();
+ if (typeof ts != "undefined") {
+ this.walk(ts);
+ }
+}
+
+JSDOC.Walker.prototype.init = function() {
+ this.ts = null;
+
+ var globalSymbol = new JSDOC.Symbol("_global_", [], "GLOBAL", new JSDOC.DocComment(""));
+ globalSymbol.isNamespace = true;
+ globalSymbol.srcFile = "";
+ globalSymbol.isPrivate = false;
+ JSDOC.Parser.addSymbol(globalSymbol);
+ this.lastDoc = null;
+ this.token = null;
+
+ /**
+ The chain of symbols under which we are currently nested.
+ @type Array
+ */
+ this.namescope = [globalSymbol];
+ this.namescope.last = function(n){ if (!n) n = 0; return this[this.length-(1+n)] || "" };
+}
+
+JSDOC.Walker.prototype.walk = function(/**JSDOC.TokenStream*/ts) {
+ this.ts = ts;
+ while (this.token = this.ts.look()) {
+ if (this.token.popNamescope) {
+
+ var symbol = this.namescope.pop();
+ if (symbol.is("FUNCTION")) {
+ if (this.ts.look(1).is("LEFT_PAREN") && symbol.comment.getTag("function").length == 0) {
+ symbol.isa = "OBJECT";
+ }
+ }
+ }
+ this.step();
+ if (!this.ts.next()) break;
+ }
+}
+
+JSDOC.Walker.prototype.step = function() {
+ if (this.token.is("JSDOC")) { // it's a doc comment
+
+ var doc = new JSDOC.DocComment(this.token.data);
+
+
+ if (doc.getTag("exports").length > 0) {
+ var exports = doc.getTag("exports")[0];
+
+ exports.desc.match(/(\S+) as (\S+)/i);
+ var n1 = RegExp.$1;
+ var n2 = RegExp.$2;
+
+ if (!n1 && n2) throw "@exports tag requires a value like: 'name as ns.name'";
+
+ JSDOC.Parser.rename = (JSDOC.Parser.rename || {});
+ JSDOC.Parser.rename[n1] = n2
+ }
+
+ if (doc.getTag("lends").length > 0) {
+ var lends = doc.getTag("lends")[0];
+
+ var name = lends.desc
+ if (!name) throw "@lends tag requires a value.";
+
+ var symbol = new JSDOC.Symbol(name, [], "OBJECT", doc);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+
+ this.lastDoc = null;
+ return true;
+ }
+ else if (doc.getTag("name").length > 0 && doc.getTag("overview").length == 0) { // it's a virtual symbol
+ var virtualName = doc.getTag("name")[0].desc;
+ if (!virtualName) throw "@name tag requires a value.";
+
+ if (doc.getTag("memberOf").length > 0) {
+ virtualName = (doc.getTag("memberOf")[0] + "." + virtualName)
+ .replace(/([#.])\./, "$1");
+ doc.deleteTag("memberOf");
+ }
+
+ var symbol = new JSDOC.Symbol(virtualName, [], "VIRTUAL", doc);
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.lastDoc = null;
+ return true;
+ }
+ else if (doc.meta) { // it's a meta doclet
+ if (doc.meta == "@+") JSDOC.DocComment.shared = doc.src;
+ else if (doc.meta == "@-") JSDOC.DocComment.shared = "";
+ else if (doc.meta == "nocode+") JSDOC.Parser.conf.ignoreCode = true;
+ else if (doc.meta == "nocode-") JSDOC.Parser.conf.ignoreCode = JSDOC.opt.n;
+ else throw "Unrecognized meta comment: "+doc.meta;
+
+ this.lastDoc = null;
+ return true;
+ }
+ else if (doc.getTag("overview").length > 0) { // it's a file overview
+ symbol = new JSDOC.Symbol("", [], "FILE", doc);
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.lastDoc = null;
+ return true;
+ }
+ else {
+ this.lastDoc = doc;
+ return false;
+ }
+ }
+ else if (!JSDOC.Parser.conf.ignoreCode) { // it's code
+ if (this.token.is("NAME")) { // it's the name of something
+ var symbol;
+ var name = this.token.data;
+ var doc = null; if (this.lastDoc) doc = this.lastDoc;
+ var params = [];
+
+ // it's inside an anonymous object
+ if (this.ts.look(1).is("COLON") && this.ts.look(-1).is("LEFT_CURLY") && !(this.ts.look(-2).is("JSDOC") || this.namescope.last().comment.getTag("lends").length || this.ts.look(-2).is("ASSIGN") || this.ts.look(-2).is("COLON"))) {
+ name = "$anonymous";
+ name = this.namescope.last().alias+"-"+name
+
+ params = [];
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken(null, "RIGHT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // function foo() {}
+ else if (this.ts.look(-1).is("FUNCTION") && this.ts.look(1).is("LEFT_PAREN")) {
+ var isInner;
+
+ if (this.lastDoc) doc = this.lastDoc;
+
+ if (doc && doc.getTag("memberOf").length > 0) {
+ name = (doc.getTag("memberOf")[0]+"."+name).replace("#.", "#");
+ doc.deleteTag("memberOf");
+ }
+ else {
+ name = this.namescope.last().alias+"-"+name;
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+ }
+
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+
+ params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
+
+ symbol = new JSDOC.Symbol(name, params, "FUNCTION", doc);
+ if (isInner) symbol.isInner = true;
+
+ if (this.ts.look(1).is("JSDOC")) {
+ var inlineReturn = ""+this.ts.look(1).data;
+ inlineReturn = inlineReturn.replace(/(^\/\*\* *| *\*\/$)/g, "");
+ symbol.type = inlineReturn;
+ }
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // foo = function() {}
+ else if (this.ts.look(1).is("ASSIGN") && this.ts.look(2).is("FUNCTION")) {
+ var constructs;
+ var isConstructor = false;
+ if (doc && (constructs = doc.getTag("constructs")) && constructs.length) {
+ if (constructs[0].desc) {
+ name = constructs[0].desc;
+ isConstructor = true;
+ }
+ }
+
+ var isInner;
+ if (this.ts.look(-1).is("VAR") || this.isInner) {
+ if (doc && doc.getTag("memberOf").length > 0) {
+ name = (doc.getTag("memberOf")[0]+"."+name).replace("#.", "#");
+ doc.deleteTag("memberOf");
+ }
+ else {
+ name = this.namescope.last().alias+"-"+name;
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+ }
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+ }
+ else if (name.indexOf("this.") == 0) {
+ name = this.resolveThis(name);
+ }
+
+ if (this.lastDoc) doc = this.lastDoc;
+ params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
+
+ symbol = new JSDOC.Symbol(name, params, "FUNCTION", doc);
+
+ if (isInner) symbol.isInner = true;
+ if (isConstructor) symbol.isa = "CONSTRUCTOR";
+
+ if (this.ts.look(1).is("JSDOC")) {
+ var inlineReturn = ""+this.ts.look(1).data;
+ inlineReturn = inlineReturn.replace(/(^\/\*\* *| *\*\/$)/g, "");
+ symbol.type = inlineReturn;
+ }
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // foo = new function() {} or foo = (function() {}
+ else if (this.ts.look(1).is("ASSIGN") && (this.ts.look(2).is("NEW") || this.ts.look(2).is("LEFT_PAREN")) && this.ts.look(3).is("FUNCTION")) {
+ var isInner;
+ if (this.ts.look(-1).is("VAR") || this.isInner) {
+ name = this.namescope.last().alias+"-"+name
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+ }
+ else if (name.indexOf("this.") == 0) {
+ name = this.resolveThis(name);
+ }
+
+ this.ts.next(3); // advance past the "new" or "("
+
+ if (this.lastDoc) doc = this.lastDoc;
+ params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+ if (isInner) symbol.isInner = true;
+
+ if (this.ts.look(1).is("JSDOC")) {
+ var inlineReturn = ""+this.ts.look(1).data;
+ inlineReturn = inlineReturn.replace(/(^\/\*\* *| *\*\/$)/g, "");
+ symbol.type = inlineReturn;
+ }
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ symbol.scopeType = "INSTANCE";
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // foo: function() {}
+ else if (this.ts.look(1).is("COLON") && this.ts.look(2).is("FUNCTION")) {
+ name = (this.namescope.last().alias+"."+name).replace("#.", "#");
+
+ if (this.lastDoc) doc = this.lastDoc;
+ params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
+
+ if (doc && doc.getTag("constructs").length) {
+ name = name.replace(/\.prototype(\.|$)/, "#");
+
+ if (name.indexOf("#") > -1) name = name.match(/(^[^#]+)/)[0];
+ else name = this.namescope.last().alias;
+
+ symbol = new JSDOC.Symbol(name, params, "CONSTRUCTOR", doc);
+ }
+ else {
+ symbol = new JSDOC.Symbol(name, params, "FUNCTION", doc);
+ }
+
+ if (this.ts.look(1).is("JSDOC")) {
+ var inlineReturn = ""+this.ts.look(1).data;
+ inlineReturn = inlineReturn.replace(/(^\/\*\* *| *\*\/$)/g, "");
+ symbol.type = inlineReturn;
+ }
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // foo = {}
+ else if (this.ts.look(1).is("ASSIGN") && this.ts.look(2).is("LEFT_CURLY")) {
+ var isInner;
+ if (this.ts.look(-1).is("VAR") || this.isInner) {
+ name = this.namescope.last().alias+"-"+name
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+ }
+ else if (name.indexOf("this.") == 0) {
+ name = this.resolveThis(name);
+ }
+
+ if (this.lastDoc) doc = this.lastDoc;
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+ if (isInner) symbol.isInner = true;
+
+
+ if (doc) JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // var foo;
+ else if (this.ts.look(1).is("SEMICOLON")) {
+ var isInner;
+
+ if (this.ts.look(-1).is("VAR") || this.isInner) {
+ name = this.namescope.last().alias+"-"+name
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+
+ if (this.lastDoc) doc = this.lastDoc;
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+ if (isInner) symbol.isInner = true;
+
+
+ if (doc) JSDOC.Parser.addSymbol(symbol);
+ }
+ }
+ // foo = x
+ else if (this.ts.look(1).is("ASSIGN")) {
+ var isInner;
+ if (this.ts.look(-1).is("VAR") || this.isInner) {
+ name = this.namescope.last().alias+"-"+name
+ if (!this.namescope.last().is("GLOBAL")) isInner = true;
+ }
+ else if (name.indexOf("this.") == 0) {
+ name = this.resolveThis(name);
+ }
+
+ if (this.lastDoc) doc = this.lastDoc;
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+ if (isInner) symbol.isInner = true;
+
+
+ if (doc) JSDOC.Parser.addSymbol(symbol);
+ }
+ // foo: {}
+ else if (this.ts.look(1).is("COLON") && this.ts.look(2).is("LEFT_CURLY")) {
+ name = (this.namescope.last().alias+"."+name).replace("#.", "#");
+
+ if (this.lastDoc) doc = this.lastDoc;
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+
+
+ if (doc) JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ // foo: x
+ else if (this.ts.look(1).is("COLON")) {
+ name = (this.namescope.last().alias+"."+name).replace("#.", "#");;
+
+ if (this.lastDoc) doc = this.lastDoc;
+
+ symbol = new JSDOC.Symbol(name, params, "OBJECT", doc);
+
+
+ if (doc) JSDOC.Parser.addSymbol(symbol);
+ }
+ // foo(...)
+ else if (this.ts.look(1).is("LEFT_PAREN")) {
+ if (typeof JSDOC.PluginManager != "undefined") {
+ var functionCall = {name: name};
+
+ var cursor = this.ts.cursor;
+ params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
+ this.ts.cursor = cursor;
+
+ for (var i = 0; i < params.length; i++)
+ functionCall["arg" + (i + 1)] = params[i].name;
+
+ JSDOC.PluginManager.run("onFunctionCall", functionCall);
+ if (functionCall.doc) {
+ this.ts.insertAhead(new JSDOC.Token(functionCall.doc, "COMM", "JSDOC"));
+ }
+ }
+ }
+ this.lastDoc = null;
+ }
+ else if (this.token.is("FUNCTION")) { // it's an anonymous function
+ if (
+ (!this.ts.look(-1).is("COLON") || !this.ts.look(-1).is("ASSIGN"))
+ && !this.ts.look(1).is("NAME")
+ ) {
+ if (this.lastDoc) doc = this.lastDoc;
+
+ name = "$anonymous";
+ name = this.namescope.last().alias+"-"+name
+
+ params = JSDOC.Walker.onParamList(this.ts.balance("LEFT_PAREN"));
+
+ symbol = new JSDOC.Symbol(name, params, "FUNCTION", doc);
+
+ JSDOC.Parser.addSymbol(symbol);
+
+ this.namescope.push(symbol);
+
+ var matching = this.ts.getMatchingToken("LEFT_CURLY");
+ if (matching) matching.popNamescope = name;
+ else LOG.warn("Mismatched } character. Can't parse code in file " + symbol.srcFile + ".");
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ Resolves what "this." means when it appears in a name.
+ @param name The name that starts with "this.".
+ @returns The name with "this." resolved.
+ */
+JSDOC.Walker.prototype.resolveThis = function(name) {
+ name.match(/^this\.(.+)$/)
+ var nameFragment = RegExp.$1;
+ if (!nameFragment) return name;
+
+ var symbol = this.namescope.last();
+ var scopeType = symbol.scopeType || symbol.isa;
+
+ // if we are in a constructor function, `this` means the instance
+ if (scopeType == "CONSTRUCTOR") {
+ name = symbol.alias+"#"+nameFragment;
+ }
+
+ // if we are in an anonymous constructor function, `this` means the instance
+ else if (scopeType == "INSTANCE") {
+ name = symbol.alias+"."+nameFragment;
+ }
+
+ // if we are in a function, `this` means the container (possibly the global)
+ else if (scopeType == "FUNCTION") {
+ // in a method of a prototype, so `this` means the constructor
+ if (symbol.alias.match(/(^.*)[#.-][^#.-]+/)) {
+ var parentName = RegExp.$1;
+ var parent = JSDOC.Parser.symbols.getSymbol(parentName);
+
+ if (!parent) {
+ if (JSDOC.Lang.isBuiltin(parentName)) parent = JSDOC.Parser.addBuiltin(parentName);
+ else {
+ if (symbol.alias.indexOf("$anonymous") < 0) // these will be ignored eventually
+ LOG.warn("Trying to document "+symbol.alias+" without first documenting "+parentName+".");
+ }
+ }
+ if (parent) name = parentName+(parent.is("CONSTRUCTOR")?"#":".")+nameFragment;
+ }
+ else {
+ parent = this.namescope.last(1);
+ name = parent.alias+(parent.is("CONSTRUCTOR")?"#":".")+nameFragment;
+ }
+ }
+ // otherwise it means the global
+ else {
+ name = nameFragment;
+ }
+
+ return name;
+}
+
+JSDOC.Walker.onParamList = function(/**Array*/paramTokens) {
+ if (!paramTokens) {
+ LOG.warn("Malformed parameter list. Can't parse code.");
+ return [];
+ }
+ var params = [];
+ for (var i = 0, l = paramTokens.length; i < l; i++) {
+ if (paramTokens[i].is("JSDOC")) {
+ var paramType = paramTokens[i].data.replace(/(^\/\*\* *| *\*\/$)/g, "");
+
+ if (paramTokens[i+1] && paramTokens[i+1].is("NAME")) {
+ i++;
+ params.push({type: paramType, name: paramTokens[i].data});
+ }
+ }
+ else if (paramTokens[i].is("NAME")) {
+ params.push({name: paramTokens[i].data});
+ }
+ }
+ return params;
+}