Spaces:
Sleeping
Sleeping
/** @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."); | |
} | |
} | |