Skip to content
Snippets Groups Projects
Commit 58f15d55 authored by Scott Graham's avatar Scott Graham
Browse files

various fiddling towards getting closure working in browser. add jsdoc-toolkit...

various fiddling towards getting closure working in browser. add jsdoc-toolkit for perhaps helper for ffi
parent 9d734e27
Branches
Tags
No related merge requests found
Showing
with 20882 additions and 21590 deletions
This diff is collapsed.
This diff is collapsed.
......@@ -31,6 +31,7 @@ Files = [
'src/module.js',
'src/generator.js',
'src/file.js',
'src/wrapped_object.js',
'src/tokenize.js',
'gen/parse_tables.js',
......@@ -40,7 +41,6 @@ Files = [
'src/symtable.js',
'src/compile.js',
'src/import.js',
'gen/googlocs.js',
("support/jsbeautify/beautify.js", 'test'),
]
......@@ -132,7 +132,7 @@ def buildDebugBrowser():
os.mkdir("support/tmp")
buildVFS()
scripts = []
for f in getFileList('test') + ["test/browser-stubs.js", "support/tmp/vfs.js"] + TestFiles:
for f in getFileList('test') + ["test/browser-stubs.js", "support/tmp/vfs.js", "gen/debug_import_all_closure.js"] + TestFiles:
scripts.append('<script type="text/javascript" src="%s"></script>' %
os.path.join('../..', f))
......@@ -561,12 +561,8 @@ def vmwareregr(names):
def regengooglocs():
"""scans the closure library and creates a mapping of what files all the
modules are located in.
add fake null entries for package init files
"""
"""scans the closure library and builds an import-everything file to be
used during dev. """
# from calcdeps.py
prov_regex = re.compile('goog\.provide\s*\(\s*[\'\"]([^\)]+)[\'\"]\s*\)')
......@@ -583,22 +579,13 @@ def regengooglocs():
for prov in prov_regex.findall(contents):
modToFile[prov] = f.lstrip(root)
# for all modules, if their parent package isn't already defined, we add a
# fake entry that's equivalent to __init__.py
def addFakeParentEntries(mod):
parent = ".".join(mod.split(".")[:-1])
if parent not in modToFile:
modToFile[parent] = "/".join(parent.split(".")) + "/__init__.js"
print parent
addFakeParentEntries(parent)
for modname in modToFile.keys():
addFakeParentEntries(modname)
with open("gen/googlocs.js", "w") as glf:
print >>glf, "Sk.googlocs ="
pprint.pprint(modToFile, glf)
print >>glf, ";"
with open("gen/debug_import_all_closure.js", "w") as glf:
keys = modToFile.keys()
keys.sort()
for m in keys:
if "demos." in m: continue
if not m.startswith("goog."): continue
print >>glf, "goog.require('%s');" % m
if __name__ == "__main__":
......
todo:
object genericgetattr is wrong. should be looking up bases, not types. dummy
make a type-name-getting function, rather than obj.tp$name so that number works (and it'd be a good error checking place too)
......@@ -87,4 +88,38 @@ in the function object that's being called.)
So, just build up a list of name/value for keywords, and .call has to
put them in the right place by looking at something. code obj? func obj?
closure binding:
1. need to handle converting from skulpt objects to js objects (for
number, bool, string) maybe only handle those 3 and use something
manual for others?
2. need to handle getting the return value to be an object that has a
tp$getattr, so getting something out of it works
3. need to handle binding methods to their objects (creating something
like a Sk.builtin.method) e.g. for g.drawRect
4. need to handle calling @constructor functions with 'new' because
closure doesn't do return this; in its ctors.
first 3 can do dynamically. there's no tag on ctors though, except in
the comment annotations.
- fork closure-compiler and generate a full set of wrappers offline?
they could even be simple python
seems like jsdoc-toolkit can handle parsing comments pretty well, seems
like a reasonable approach. at least we could build a list of ctors.
maybe do 1-3 dynamically, and just put ctors in a table and change .call
to handle the 'new' stupid magic?
# vim: set tw=72:
......@@ -49,20 +49,36 @@ Sk.importSearchPathForName = function(name, ext, failok)
Sk.loadClosureModule = function(name, filename)
{
goog.asserts.assert(filename.lastIndexOf(".js") == filename.length - 3);
var fnWithoutExt = filename.substr(0, filename.length - 3);
var fn = Sk.importSearchPathForName(fnWithoutExt, ".js");
//var rawSrc = Sk.read(fn);
var rawSrc = "goog.require('" + name + "');";
if (document !== undefined)
{
//goog.global.eval(rawSrc);
rawSrc = "";
}
// we can't just return the closure object as the locals dict because it
// gets assigned to inst$dict. When a submodule or subpackage is imported,
// it'll be assigned to the parent module under that name, which would
// overwrite itself. For example, if we returned the 'goog' object when
// importing goog (as it's an object that contains all the locals), then
// when we import goog.json, the goog.json-Sk.module would be assigned
// over top of goog.json (the JS object), which means that goog.json
// wouldn't be accessible from JS any more (only via tp$getattr). So, we
// do a shallow copy of the 'module' here to create a new object for the
// module's inst$dict.
var wrap = "\n" +
"var $closuremodule = function(name) {" +
"var $closuremodule = function(name) { /*" + name + "*/" +
"var $loc = {};\n" +
"for (var nat in " + name + "){" +
name + "[nat].$isnative=true;" +
"}" +
"return " + name + ";" +
"$loc[nat] = " + name + "[nat];\n" +
"if(typeof $loc[nat] === 'function'){\n" +
"$loc[nat].$isnative=true;\n" +
"}}" +
"return $loc;\n" +
"};";
print(wrap);
return { funcname: "$closuremodule", code: rawSrc + wrap };
};
......@@ -89,6 +105,7 @@ Sk.importSetUpPath = function()
Sk.importModuleInternal_ = function(name, dumpJS, modname)
{
//dumpJS = true;
Sk.importSetUpPath();
// if no module name override, supplied, use default name
......@@ -135,13 +152,12 @@ Sk.importModuleInternal_ = function(name, dumpJS, modname)
filename = builtinfn;
co = { funcname: "$builtinmodule", code: Sk.read(filename) };
}
else if ((googClosure = Sk.googlocs[name]) !== undefined)
else if (name.indexOf("goog") == 0) // special case for goog closure
{
//print("importing closure module", googClosure);
if (googClosure.indexOf("__init__.js") !== -1) // special entry for fake __init__.py/js
co = Sk.compile("\n", googClosure, "exec");
if (goog.global.eval(name) === undefined)
co = Sk.compile("\n", googClosure, "exec"); // assume it's a package, so make an empty module
else
co = Sk.loadClosureModule(name, googClosure);
co = Sk.loadClosureModule(name);
}
else
{
......@@ -154,7 +170,7 @@ Sk.importModuleInternal_ = function(name, dumpJS, modname)
if (!COMPILED)
{
if (dumpJS)
//if (dumpJS)
{
print("-----");
var withLineNumbers = function(code)
......
......@@ -336,8 +336,27 @@ Sk.misceval.apply = function(func, kw, args)
// function around generators (that creates the iterator).
// should just make that a real function object and get rid
// of this case.
if (func.$isnative) // a closure function
{
// todo; for now, lame attempt to 'marshal' between python and js
debugger;
for (var i = 0; i < args.length; ++i)
{
if (args[i].ob$type && args[i].v)
args[i] = args[i].v;
}
var ret = func.apply(null, args);
// if it's native, we want to return something that has a
// tp$getattr. todo; need to do this for typeof ret === object,
// but callables need to be functions
return new Sk.builtin.wrappedObject(ret);
}
else
{
debugger;
return func.apply(null, args);
}
}
else
{
var fcall = func.tp$call;
......
/**
* @constructor
*/
Sk.builtin.wrappedObject = function(dict)
{
this.inst$dict = dict;
};
Sk.builtin.wrappedObject.prototype.HashNotImplemented = function()
{
throw new Sk.builtin.TypeError("unhashable type: '" + this.tp$name + "'");
};
Sk.builtin.wrappedObject.prototype.tp$getattr = function(name)
{
var retVal = Sk.builtin.object.prototype.GenericGetAttr.call(this, name);
if (typeof retVal === "function")
{
return new Sk.builtin.method(retVal, this);
}
return retVal;
};
// todo; what should tp$setattr do?
Sk.builtin.wrappedObject.prototype.ob$type = Sk.builtin.type.makeTypeObj('wrappedObject', new Sk.builtin.wrappedObject(undefined));
======================================================================
DESCRIPTION:
This is the source code for JsDoc Toolkit, an automatic documentation
generation tool for JavaScript. It is written in JavaScript and is run
from a command line (or terminal) using Java and Mozilla's Rhino
JavaScript runtime engine.
Using this tool you can automatically turn JavaDoc-like comments in
your JavaScript source code into published output files, such as HTML
or XML.
For more information, to report a bug, or to browse the technical
documentation for this tool please visit the official JsDoc Toolkit
project homepage at http://code.google.com/p/jsdoc-toolkit/
For the most up-to-date documentation on JsDoc Toolkit see the
official wiki at http://code.google.com/p/jsdoc-toolkit/w/list
======================================================================
REQUIREMENTS:
JsDoc Toolkit is known to work with:
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
on Windows XP,
and java version "1.5.0_19"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_19-b02-304)
on Mac OS X 10.5.
Other versions of java may or may not work with JsDoc Toolkit.
======================================================================
USAGE:
Running JsDoc Toolkit requires you to have Java installed on your
computer. For more information see http://www.java.com/getjava/
Before running the JsDoc Toolkit app you should change your current
working directory to the jsdoc-toolkit folder. Then follow the
examples below, or as shown on the project wiki.
On a computer running Windows a valid command line to run JsDoc
Toolkit might look like this:
> java -jar jsrun.jar app\run.js -a -t=templates\jsdoc mycode.js
On Mac OS X or Linux the same command would look like this:
$ java -jar jsrun.jar app/run.js -a -t=templates/jsdoc mycode.js
The above assumes your current working directory contains jsrun.jar,
the "app" and "templates" subdirectories from the standard JsDoc
Toolkit distribution and that the relative path to the code you wish
to document is "mycode.js".
The output documentation files will be saved to a new directory named
"out" (by default) in the current directory, or if you specify a
-d=somewhere_else option, to the somewhere_else directory.
For help (usage notes) enter this on the command line:
$ java -jar jsrun.jar app/run.js --help
More information about the various command line options used by JsDoc
Toolkit are available on the project wiki.
======================================================================
RUNNING VIA SHELL SCRIPT
Avi Deitcher has contributed the file jsrun.sh with the following usage notes:
A script to simplify running jsdoc from the command-line, especially when
running from within a development or build environment such as ant.
Normally, to run jsdoc, you need a command-line as the following:
java -Djsdoc.dir=/some/long/dir/path/to/jsdoc -jar
/some/long/dir/path/to/jsdoc/jsrun.jar /some/long/dir/path/to/jsdoc/app/run.js
-t=template -r=4 /some/long/dir/path/to/my/src/code
This can get tedious to redo time and again, and difficult to use from within a build environment.
To simplify the process, jsrun.sh will automatically run this path, as well as passing through any arguments.
Usage: jsrun.sh <run.js arguments>
All <run.js arguments> will be passed through.
Additionally, jsrun.sh will take the following actions:
1) If the environment variable JSDOCDIR is set, it will add
"-Djsdoc.dir=$JSDOCDIR" to the command-line
2) If the environment variable JSDOCTEMPLATEDIR is set, it will add
"-Djsdoc.template.dir=$JSDOCTEMPLATEDIR" to the command-line
3) java with the appropriate path to jsrun.jar and run.js will be instantiated
If not variables are set, it is assumed that the path to jsrun.jar and app/ is in the current working directory.
Example:
# jsrun.sh ./src/
Assuming JSDOCDIR=/some/path/to/my/jsdoc will cause the following command to
execute:
java -Djsdoc.dir=/some/path/to/my/jsdoc -jar /some/path/to/my/jsdoc/jsrun.jar
/some/path/to/my/jsdoc/app/run.js ./src/
======================================================================
TESTING:
To run the suite of unit tests included with JsDoc Toolkit enter this
on the command line:
$ java -jar jsrun.jar app/run.js -T
To see a dump of the internal data structure that JsDoc Toolkit has
built from your source files use this command:
$ java -jar jsrun.jar app/run.js mycode.js -Z
======================================================================
LICENSE:
JSDoc.pm
This project is based on the JSDoc.pm tool, created by Michael
Mathews and Gabriel Reid. More information on JsDoc.pm can
be found on the JSDoc.pm homepage: http://jsdoc.sourceforge.net/
Complete documentation on JsDoc Toolkit can be found on the project
wiki at http://code.google.com/p/jsdoc-toolkit/w/list
Rhino
Rhino (JavaScript in Java) is open source and licensed by Mozilla
under the MPL 1.1 or later/GPL 2.0 or later licenses, the text of
which is available at http://www.mozilla.org/MPL/
You can obtain the source code for Rhino from the Mozilla web site at
http://www.mozilla.org/rhino/download.html
JsDoc Toolkit is a larger work that uses the Rhino JavaScript engine
but is not derived from it in any way. The Rhino library is used
without modification and without any claims whatsoever.
The Rhino Debugger
You can obtain more information about the Rhino Debugger from the
Mozilla web site at http://www.mozilla.org/rhino/debugger.html
JsDoc Toolkit is a larger work that uses the Rhino Debugger but
is not derived from it in any way. The Rhino Debugger is used
without modification and without any claims whatsoever.
JsDoc Toolkit
All code specific to JsDoc Toolkit are free, open source and licensed
for use under the X11/MIT License.
JsDoc Toolkit is Copyright (c)2009 Michael Mathews <micmath@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms below.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions: The above copyright notice and this
permission notice must be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
IO.include("frame/Opt.js");
IO.include("frame/Chain.js");
IO.include("frame/Link.js");
IO.include("frame/String.js");
IO.include("frame/Hash.js");
IO.include("frame/Namespace.js");
//IO.include("frame/Reflection.js");
/** A few helper functions to make life a little easier. */
function defined(o) {
return (o !== undefined);
}
function copy(o) { // todo check for circular refs
if (o == null || typeof(o) != 'object') return o;
var c = new o.constructor();
for(var p in o) c[p] = copy(o[p]);
return c;
}
function isUnique(arr) {
var l = arr.length;
for(var i = 0; i < l; i++ ) {
if (arr.lastIndexOf(arr[i]) > i) return false;
}
return true;
}
/** Returns the given string with all regex meta characters backslashed. */
RegExp.escapeMeta = function(str) {
return str.replace(/([$^\\\/()|?+*\[\]{}.-])/g, "\\$1");
}
/**@constructor*/
function ChainNode(object, link) {
this.value = object;
this.link = link; // describes this node's relationship to the previous node
}
/**@constructor*/
function Chain(valueLinks) {
this.nodes = [];
this.cursor = -1;
if (valueLinks && valueLinks.length > 0) {
this.push(valueLinks[0], "//");
for (var i = 1, l = valueLinks.length; i < l; i+=2) {
this.push(valueLinks[i+1], valueLinks[i]);
}
}
}
Chain.prototype.push = function(o, link) {
if (this.nodes.length > 0 && link) this.nodes.push(new ChainNode(o, link));
else this.nodes.push(new ChainNode(o));
}
Chain.prototype.unshift = function(o, link) {
if (this.nodes.length > 0 && link) this.nodes[0].link = link;
this.nodes.unshift(new ChainNode(o));
this.cursor++;
}
Chain.prototype.get = function() {
if (this.cursor < 0 || this.cursor > this.nodes.length-1) return null;
return this.nodes[this.cursor];
}
Chain.prototype.first = function() {
this.cursor = 0;
return this.get();
}
Chain.prototype.last = function() {
this.cursor = this.nodes.length-1;
return this.get();
}
Chain.prototype.next = function() {
this.cursor++;
return this.get();
}
Chain.prototype.prev = function() {
this.cursor--;
return this.get();
}
Chain.prototype.toString = function() {
var string = "";
for (var i = 0, l = this.nodes.length; i < l; i++) {
if (this.nodes[i].link) string += " -("+this.nodes[i].link+")-> ";
string += this.nodes[i].value.toString();
}
return string;
}
Chain.prototype.joinLeft = function() {
var result = "";
for (var i = 0, l = this.cursor; i < l; i++) {
if (result && this.nodes[i].link) result += this.nodes[i].link;
result += this.nodes[i].value.toString();
}
return result;
}
/* USAGE:
var path = "one/two/three.four/five-six";
var pathChain = new Chain(path.split(/([\/.-])/));
print(pathChain);
var lineage = new Chain();
lineage.push("Port");
lineage.push("Les", "son");
lineage.push("Dawn", "daughter");
lineage.unshift("Purdie", "son");
print(lineage);
// walk left
for (var node = lineage.last(); node !== null; node = lineage.prev()) {
print("< "+node.value);
}
// walk right
var node = lineage.first()
while (node !== null) {
print(node.value);
node = lineage.next();
if (node && node.link) print("had a "+node.link+" named");
}
*/
\ No newline at end of file
/**
* @class
<pre>
This is a lightly modified version of Kevin Jones' JavaScript
library Data.Dump. To download the original visit:
<a href="http://openjsan.org/doc/k/ke/kevinj/Data/Dump/">http://openjsan.org/doc/k/ke/kevinj/Data/Dump/</a>
AUTHORS
The Data.Dump JavaScript module is written by Kevin Jones
(kevinj@cpan.org), based on Data::Dump by Gisle Aas (gisle@aas.no),
based on Data::Dumper by Gurusamy Sarathy (gsar@umich.edu).
COPYRIGHT
Copyright 2007 Kevin Jones. Copyright 1998-2000,2003-2004 Gisle Aas.
Copyright 1996-1998 Gurusamy Sarathy.
This program is free software; you can redistribute it and/or modify
it under the terms of the Perl Artistic License
See http://www.perl.com/perl/misc/Artistic.html
</pre>
* @static
*/
Dumper = {
/** @param [...] The objects to dump. */
dump: function () {
if (arguments.length > 1)
return this._dump(arguments);
else if (arguments.length == 1)
return this._dump(arguments[0]);
else
return "()";
},
_dump: function (obj) {
if (typeof obj == 'undefined') return 'undefined';
var out;
if (obj.serialize) { return obj.serialize(); }
var type = this._typeof(obj);
if (obj.circularReference) obj.circularReference++;
switch (type) {
case 'circular':
out = "{ //circularReference\n}";
break;
case 'object':
var pairs = new Array;
for (var prop in obj) {
if (prop != "circularReference" && obj.hasOwnProperty(prop)) { //hide inherited properties
pairs.push(prop + ': ' + this._dump(obj[prop]));
}
}
out = '{' + this._format_list(pairs) + '}';
break;
case 'string':
for (var prop in Dumper.ESC) {
if (Dumper.ESC.hasOwnProperty(prop)) {
obj = obj.replace(prop, Dumper.ESC[prop]);
}
}
// Escape UTF-8 Strings
if (obj.match(/^[\x00-\x7f]*$/)) {
out = '"' + obj.replace(/\"/g, "\\\"").replace(/([\n\r]+)/g, "\\$1") + '"';
}
else {
out = "unescape('"+escape(obj)+"')";
}
break;
case 'array':
var elems = new Array;
for (var i=0; i<obj.length; i++) {
elems.push( this._dump(obj[i]) );
}
out = '[' + this._format_list(elems) + ']';
break;
case 'date':
// firefox returns GMT strings from toUTCString()...
var utc_string = obj.toUTCString().replace(/GMT/,'UTC');
out = 'new Date("' + utc_string + '")';
break;
case 'element':
// DOM element
out = this._dump_dom(obj);
break;
default:
out = obj;
}
out = String(out).replace(/\n/g, '\n ');
out = out.replace(/\n (.*)$/,"\n$1");
return out;
},
_format_list: function (list) {
if (!list.length) return '';
var nl = list.toString().length > 60 ? '\n' : ' ';
return nl + list.join(',' + nl) + nl;
},
_typeof: function (obj) {
if (obj && obj.circularReference && obj.circularReference > 1) return 'circular';
if (Array.prototype.isPrototypeOf(obj)) return 'array';
if (Date.prototype.isPrototypeOf(obj)) return 'date';
if (typeof obj.nodeType != 'undefined') return 'element';
return typeof(obj);
},
_dump_dom: function (obj) {
return '"' + Dumper.nodeTypes[obj.nodeType] + '"';
}
};
Dumper.ESC = {
"\t": "\\t",
"\n": "\\n",
"\f": "\\f"
};
Dumper.nodeTypes = {
1: "ELEMENT_NODE",
2: "ATTRIBUTE_NODE",
3: "TEXT_NODE",
4: "CDATA_SECTION_NODE",
5: "ENTITY_REFERENCE_NODE",
6: "ENTITY_NODE",
7: "PROCESSING_INSTRUCTION_NODE",
8: "COMMENT_NODE",
9: "DOCUMENT_NODE",
10: "DOCUMENT_TYPE_NODE",
11: "DOCUMENT_FRAGMENT_NODE",
12: "NOTATION_NODE"
};
\ No newline at end of file
/**
@constructor
@example
var _index = new Hash();
_index.set("a", "apple");
_index.set("b", "blue");
_index.set("c", "coffee");
for (var p = _index.first(); p; p = _index.next()) {
print(p.key+" is for "+p.value);
}
*/
var Hash = function() {
this._map = {};
this._keys = [];
this._vals = [];
this.reset();
}
Hash.prototype.set = function(k, v) {
if (k != "") {
this._keys.push(k);
this._map["="+k] = this._vals.length;
this._vals.push(v);
}
}
Hash.prototype.replace = function(k, k2, v) {
if (k == k2) return;
var offset = this._map["="+k];
this._keys[offset] = k2;
if (typeof v != "undefined") this._vals[offset] = v;
this._map["="+k2] = offset;
delete(this._map["="+k]);
}
Hash.prototype.drop = function(k) {
if (k != "") {
var offset = this._map["="+k];
this._keys.splice(offset, 1);
this._vals.splice(offset, 1);
delete(this._map["="+k]);
for (var p in this._map) {
if (this._map[p] >= offset) this._map[p]--;
}
if (this._cursor >= offset && this._cursor > 0) this._cursor--;
}
}
Hash.prototype.get = function(k) {
if (k != "") {
return this._vals[this._map["="+k]];
}
}
Hash.prototype.keys = function() {
return this._keys;
}
Hash.prototype.hasKey = function(k) {
if (k != "") {
return (typeof this._map["="+k] != "undefined");
}
}
Hash.prototype.values = function() {
return this._vals;
}
Hash.prototype.reset = function() {
this._cursor = 0;
}
Hash.prototype.first = function() {
this.reset();
return this.next();
}
Hash.prototype.next = function() {
if (this._cursor++ < this._keys.length)
return {key: this._keys[this._cursor-1], value: this._vals[this._cursor-1]};
}
\ No newline at end of file
/** Handle the creation of HTML links to documented symbols.
@constructor
*/
function Link() {
this.alias = "";
this.src = "";
this.file = "";
this.text = "";
this.innerName = "";
this.classLink = false;
this.targetName = "";
this.target = function(targetName) {
if (defined(targetName)) this.targetName = targetName;
return this;
}
this.inner = function(inner) {
if (defined(inner)) this.innerName = inner;
return this;
}
this.withText = function(text) {
if (defined(text)) this.text = text;
return this;
}
this.toSrc = function(filename) {
if (defined(filename)) this.src = filename;
return this;
}
this.toSymbol = function(alias) {
if (defined(alias)) this.alias = new String(alias);
return this;
}
this.toClass = function(alias) {
this.classLink = true;
return this.toSymbol(alias);
}
this.toFile = function(file) {
if (defined(file)) this.file = file;
return this;
}
this.toString = function() {
var linkString;
var thisLink = this;
if (this.alias) {
linkString = this.alias.replace(/(^|[^a-z$0-9_#.:^-])([|a-z$0-9_#.:^-]+)($|[^a-z$0-9_#.:^-])/i,
function(match, prematch, symbolName, postmatch) {
var symbolNames = symbolName.split("|");
var links = [];
for (var i = 0, l = symbolNames.length; i < l; i++) {
thisLink.alias = symbolNames[i];
links.push(thisLink._makeSymbolLink(symbolNames[i]));
}
return prematch+links.join("|")+postmatch;
}
);
}
else if (this.src) {
linkString = thisLink._makeSrcLink(this.src);
}
else if (this.file) {
linkString = thisLink._makeFileLink(this.file);
}
return linkString;
}
}
/** prefixed for hashes */
Link.hashPrefix = "";
/** Appended to the front of relative link paths. */
Link.base = "";
Link.symbolNameToLinkName = function(symbol) {
var linker = "",
ns = "";
if (symbol.isStatic) linker = ".";
else if (symbol.isInner) linker = "-";
if (symbol.isEvent && !/^event:/.test(symbol.name)) {
ns = "event:";
}
return Link.hashPrefix+linker+ns+symbol.name;
}
Link.getSymbol= function(alias) {
var symbol= Link.symbolSet.getSymbol(alias);
if (symbol)
return symbol;
if ('#'!==alias.charAt(0) || !Link.currentSymbol)
return null;
// resolve relative name
var container= Link.currentSymbol;
while (container)
{
symbol= Link.symbolSet.getSymbol(container.alias + alias);
if (symbol)
return symbol;
// No superclass
if (!container.augments.length)
return null;
container= Link.symbolSet.getSymbol(container.augments[0].desc);
}
return null;
}
/** Create a link to another symbol. */
Link.prototype._makeSymbolLink = function(alias) {
var linkBase = Link.base+publish.conf.symbolsDir;
var linkTo = Link.getSymbol(alias);
var linkPath;
var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
// if there is no symbol by that name just return the name unaltered
if (!linkTo)
return this.text || alias;
// it's a symbol in another file
else {
if (!linkTo.is("CONSTRUCTOR") && !linkTo.isNamespace) { // it's a method or property
linkPath= (Link.filemap) ? Link.filemap[linkTo.memberOf] :
escape(linkTo.memberOf) || "_global_";
linkPath += publish.conf.ext + "#" + Link.symbolNameToLinkName(linkTo);
}
else {
linkPath = (Link.filemap)? Link.filemap[linkTo.alias] : escape(linkTo.alias);
linkPath += publish.conf.ext;// + (this.classLink? "":"#" + Link.hashPrefix + "constructor");
}
linkPath = linkBase + linkPath
}
var linkText= this.text || alias;
var link = {linkPath: linkPath, linkText: linkText, linkInner: (this.innerName? "#"+this.innerName : "")};
if (typeof JSDOC.PluginManager != "undefined") {
JSDOC.PluginManager.run("onSymbolLink", link);
}
return "<a href=\""+link.linkPath+link.linkInner+"\""+target+">"+link.linkText+"</a>";
}
/** Create a link to a source file. */
Link.prototype._makeSrcLink = function(srcFilePath) {
var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
// transform filepath into a filename
var srcFile = srcFilePath.replace(/\.\.?[\\\/]/g, "").replace(/[:\\\/]/g, "_");
var outFilePath = Link.base + publish.conf.srcDir + srcFile + publish.conf.ext;
if (!this.text) this.text = FilePath.fileName(srcFilePath);
return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>";
}
/** Create a link to a source file. */
Link.prototype._makeFileLink = function(filePath) {
var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
var outFilePath = Link.base + filePath;
if (!this.text) this.text = filePath;
return "<a href=\""+outFilePath+"\""+target+">"+this.text+"</a>";
}
\ No newline at end of file
_global_ = this;
function Namespace(name, f) {
var n = name.split(".");
for (var o = _global_, i = 0, l = n.length; i < l; i++) {
o = o[n[i]] = o[n[i]] || {};
}
if (f) f();
}
\ No newline at end of file
/** @namespace */
Opt = {
/**
* Get commandline option values.
* @param {Array} args Commandline arguments. Like ["-a=xml", "-b", "--class=new", "--debug"]
* @param {object} optNames Map short names to long names. Like {a:"accept", b:"backtrace", c:"class", d:"debug"}.
* @return {object} Short names and values. Like {a:"xml", b:true, c:"new", d:true}
*/
get: function(args, optNames) {
var opt = {"_": []}; // the unnamed option allows multiple values
for (var i = 0; i < args.length; i++) {
var arg = new String(args[i]);
var name;
var value;
if (arg.charAt(0) == "-") {
if (arg.charAt(1) == "-") { // it's a longname like --foo
arg = arg.substring(2);
var m = arg.split("=");
name = m.shift();
value = m.shift();
if (typeof value == "undefined") value = true;
for (var n in optNames) { // convert it to a shortname
if (name == optNames[n]) {
name = n;
}
}
}
else { // it's a shortname like -f
arg = arg.substring(1);
var m = arg.split("=");
name = m.shift();
value = m.shift();
if (typeof value == "undefined") value = true;
for (var n in optNames) { // find the matching key
if (name == n || name+'[]' == n) {
name = n;
break;
}
}
}
if (name.match(/(.+)\[\]$/)) { // it's an array type like n[]
name = RegExp.$1;
if (!opt[name]) opt[name] = [];
}
if (opt[name] && opt[name].push) {
opt[name].push(value);
}
else {
opt[name] = value;
}
}
else { // not associated with any optname
opt._.push(args[i]);
}
}
return opt;
}
}
/*t:
plan(11, "Testing Opt.");
is(
typeof Opt,
"object",
"Opt is an object."
);
is(
typeof Opt.get,
"function",
"Opt.get is a function."
);
var optNames = {a:"accept", b:"backtrace", c:"class", d:"debug", "e[]":"exceptions"};
var t_options = Opt.get(["-a=xml", "-b", "--class=new", "--debug", "-e=one", "-e=two", "foo", "bar"], optNames);
is(
t_options.a,
"xml",
"an option defined with a short name can be accessed by its short name."
);
is(
t_options.b,
true,
"an option defined with a short name and no value are true."
);
is(
t_options.c,
"new",
"an option defined with a long name can be accessed by its short name."
);
is(
t_options.d,
true,
"an option defined with a long name and no value are true."
);
is(
typeof t_options.e,
"object",
"an option that can accept multiple values is defined."
);
is(
t_options.e.length,
2,
"an option that can accept multiple values can have more than one value."
);
is(
t_options.e[1],
"two",
"an option that can accept multiple values can be accessed as an array."
);
is(
typeof t_options._,
"object",
"the property '_' is defined for unnamed options."
);
is(
t_options._[0],
"foo",
"the property '_' can be accessed as an array."
);
*/
\ No newline at end of file
/**@constructor*/
function Reflection(obj) {
this.obj = obj;
}
Reflection.prototype.getConstructorName = function() {
if (this.obj.constructor.name) return this.obj.constructor.name;
var src = this.obj.constructor.toSource();
var name = src.substring(name.indexOf("function")+8, src.indexOf('(')).replace(/ /g,'');
return name;
}
Reflection.prototype.getMethod = function(name) {
for (var p in this.obj) {
if (p == name && typeof(this.obj[p]) == "function") return this.obj[p];
}
return null;
}
Reflection.prototype.getParameterNames = function() {
var src = this.obj.toSource();
src = src.substring(
src.indexOf("(", 8)+1, src.indexOf(")")
);
return src.split(/, ?/);
}
/**
@name String
@class Additions to the core string object.
*/
/** @author Steven Levithan, released as public domain. */
String.prototype.trim = function() {
var str = this.replace(/^\s+/, '');
for (var i = str.length - 1; i >= 0; i--) {
if (/\S/.test(str.charAt(i))) {
str = str.substring(0, i + 1);
break;
}
}
return str;
}
/*t:
plan(6, "Testing String.prototype.trim.");
var s = " a bc ".trim();
is(s, "a bc", "multiple spaces front and back are trimmed.");
s = "a bc\n\n".trim();
is(s, "a bc", "newlines only in back are trimmed.");
s = "\ta bc".trim();
is(s, "a bc", "tabs only in front are trimmed.");
s = "\n \t".trim();
is(s, "", "an all-space string is trimmed to empty.");
s = "a b\nc".trim();
is(s, "a b\nc", "a string with no spaces in front or back is trimmed to itself.");
s = "".trim();
is(s, "", "an empty string is trimmed to empty.");
*/
String.prototype.balance = function(open, close) {
var i = 0;
while (this.charAt(i) != open) {
if (i == this.length) return [-1, -1];
i++;
}
var j = i+1;
var balance = 1;
while (j < this.length) {
if (this.charAt(j) == open) balance++;
if (this.charAt(j) == close) balance--;
if (balance == 0) break;
j++;
if (j == this.length) return [-1, -1];
}
return [i, j];
}
/*t:
plan(16, "Testing String.prototype.balance.");
var s = "{abc}".balance("{","}");
is(s[0], 0, "opener in first is found.");
is(s[1], 4, "closer in last is found.");
s = "ab{c}de".balance("{","}");
is(s[0], 2, "opener in middle is found.");
is(s[1], 4, "closer in middle is found.");
s = "a{b{c}de}f".balance("{","}");
is(s[0], 1, "nested opener is found.");
is(s[1], 8, "nested closer is found.");
s = "{}".balance("{","}");
is(s[0], 0, "opener with no content is found.");
is(s[1], 1, "closer with no content is found.");
s = "".balance("{","}");
is(s[0], -1, "empty string opener is -1.");
is(s[1], -1, "empty string closer is -1.");
s = "{abc".balance("{","}");
is(s[0], -1, "opener with no closer returns -1.");
is(s[1], -1, "no closer returns -1.");
s = "abc".balance("{","}");
is(s[0], -1, "no opener or closer returns -1 for opener.");
is(s[1], -1, "no opener or closer returns -1 for closer.");
s = "a<bc}de".balance("<","}");
is(s[0], 1, "unmatching opener is found.");
is(s[1], 4, "unmatching closer is found.");
*/
\ No newline at end of file
/**
* @fileOverview
* @name JsTestrun
* @author Michael Mathews micmath@gmail.com
* @url $HeadURL: http://jsdoc-toolkit.googlecode.com/svn/trunk/jsdoc-toolkit/app/frame/Testrun.js $
* @revision $Id: Testrun.js 418 2008-01-15 21:40:33Z micmath $
* @license <a href="http://en.wikipedia.org/wiki/MIT_License">X11/MIT License</a>
* (See the accompanying README file for full details.)
*/
/**
Yet another unit testing tool for JavaScript.
@author Michael Mathews <a href="mailto:micmath@gmail.com">micmath@gmail.com</a>
@param {object} testCases Properties are testcase names, values are functions to execute as tests.
*/
function testrun(testCases) {
var ran = 0;
for (t in testCases) {
var result = testCases[t]();
ran++;
}
return testrun.reportOut+"-------------------------------\n"+((testrun.fails>0)? ":( Failed "+testrun.fails+"/" : ":) Passed all ")+testrun.count+" test"+((testrun.count == 1)? "":"s")+".\n";
}
testrun.count = 0;
testrun.current = null;
testrun.passes = 0;
testrun.fails = 0;
testrun.reportOut = "";
/** @private */
testrun.report = function(text) {
testrun.reportOut += text+"\n";
}
/**
Check if test evaluates to true.
@param {string} test To be evaluated.
@param {string} message Optional. To be displayed in the report.
@return {boolean} True if the string test evaluates to true.
*/
ok = function(test, message) {
testrun.count++;
var result;
try {
result = eval(test);
if (result) {
testrun.passes++;
testrun.report(" OK "+testrun.count+" - "+((message != null)? message : ""));
}
else {
testrun.fails++;
testrun.report("NOT OK "+testrun.count+" - "+((message != null)? message : ""));
}
}
catch(e) {
testrun.fails++
testrun.report("NOT OK "+testrun.count+" - "+((message != null)? message : ""));
}
}
/**
Check if test is same as expected.
@param {string} test To be evaluated.
@param {string} expected
@param {string} message Optional. To be displayed in the report.
@return {boolean} True if (test == expected). Note that the comparison is not a strict equality check.
*/
is = function(test, expected, message) {
testrun.count++;
var result;
try {
result = eval(test);
if (result == expected) {
testrun.passes++
testrun.report(" OK "+testrun.count+" - "+((message != null)? message : ""));
}
else {
testrun.fails++
testrun.report("NOT OK "+testrun.count+" - "+((message != null)? message : ""));
testrun.report("expected: "+expected);
testrun.report(" got: "+result);
}
}
catch(e) {
testrun.fails++
testrun.report("NOT OK "+testrun.count+" - "+((message != null)? message : ""));
testrun.report("expected: "+expected);
testrun.report(" got: "+result);}
}
/**
Check if test matches pattern.
@param {string} test To be evaluated.
@param {string} pattern Used to create a RegExp.
@param {string} message Optional. To be displayed in the report.
@return {boolean} True if test matches pattern.
*/
like = function(test, pattern, message) {
testrun.count++;
var result;
try {
result = eval(test);
var rgx = new RegExp(pattern);
if (rgx.test(result)) {
testrun.passes++
testrun.report(" OK "+testrun.count+" - "+((message != null)? message : ""));
}
else {
testrun.fails++
testrun.report("NOT OK "+testrun.count+" - "+((message != null)? message : ""));
testrun.report(" this: "+result);
testrun.report("is not like: "+pattern);
}
}
catch(e) {
testrun.fails++
testrun.report("NOT OK "+testrun.count+" - "+((message != null)? message : ""));
}
}
\ No newline at end of file
/**
This is the main container for the FOODOC handler.
@namespace
*/
FOODOC = {
};
/** The current version string of this application. */
FOODOC.VERSION = "1.0";
FOODOC.handle = function(srcFile, src) {
LOG.inform("Handling file '" + srcFile + "'");
return [
new JSDOC.Symbol(
"foo",
[],
"VIRTUAL",
new JSDOC.DocComment("/** This is a foo. */")
)
];
};
FOODOC.publish = function(symbolgroup) {
LOG.inform("Publishing symbolgroup.");
};
/**
* This is the main container for the XMLDOC handler.
* @namespace
* @author Brett Fattori (bfattori@fry.com)
* @version $Revision: 498 $
*/
XMLDOC = {
};
/** The current version string of this application. */
XMLDOC.VERSION = "1.0";
/** Include the library necessary to handle XML files */
IO.includeDir("handlers/XMLDOC/");
/**
* @type Symbol[]
*/
XMLDOC.handle = function(srcFile, src) {
};
XMLDOC.publish = function(symbolgroup) {
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment