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."); | |
| } | |
| } | |