/tags/jsdoc_toolkit-2.0.1/jsdoc-toolkit/app/lib/JSDOC/SymbolSet.js

http://jsdoc-toolkit.googlecode.com/ · JavaScript · 220 lines · 175 code · 34 blank · 11 comment · 57 complexity · 8df6e2e432f67df3f8f6db6dde9ec398 MD5 · raw file

  1. if (typeof JSDOC == "undefined") JSDOC = {};
  2. /** @constructor */
  3. JSDOC.SymbolSet = function() {
  4. this.init();
  5. }
  6. JSDOC.SymbolSet.prototype.init = function() {
  7. this._index = {};
  8. }
  9. JSDOC.SymbolSet.prototype.keys = function() {
  10. var found = [];
  11. for (var p in this._index) {
  12. found.push(p);
  13. }
  14. return found;
  15. }
  16. JSDOC.SymbolSet.prototype.hasSymbol = function(alias) {
  17. return this._index.hasOwnProperty(alias);
  18. }
  19. JSDOC.SymbolSet.prototype.addSymbol = function(symbol) {
  20. if (this.hasSymbol(symbol.alias)) {
  21. LOG.warn("Overwriting symbol documentation for: "+symbol.alias + ".");
  22. }
  23. this._index[symbol.alias] = symbol;
  24. }
  25. JSDOC.SymbolSet.prototype.getSymbol = function(alias) {
  26. if (this.hasSymbol(alias)) return this._index[alias];
  27. }
  28. JSDOC.SymbolSet.prototype.getSymbolByName = function(name) {
  29. for (var p in this._index) {
  30. var symbol = this.getSymbol(p);
  31. if (symbol.name == name) return symbol;
  32. }
  33. }
  34. JSDOC.SymbolSet.prototype.toArray = function() {
  35. var found = [];
  36. for (var p in this._index) {
  37. found.push(this._index[p]);
  38. }
  39. return found;
  40. }
  41. JSDOC.SymbolSet.prototype.deleteSymbol = function(alias) {
  42. if (!this.hasSymbol(alias)) return;
  43. delete this._index[alias];
  44. }
  45. JSDOC.SymbolSet.prototype.renameSymbol = function(oldName, newName) {
  46. // todo: should check if oldname or newname already exist
  47. this._index[newName] = this._index[oldName];
  48. this.deleteSymbol(oldName);
  49. this._index[newName].alias = newName;
  50. return newName;
  51. }
  52. JSDOC.SymbolSet.prototype.relate = function() {
  53. this.resolveBorrows();
  54. this.resolveMemberOf();
  55. this.resolveAugments();
  56. }
  57. JSDOC.SymbolSet.prototype.resolveBorrows = function() {
  58. for (p in this._index) {
  59. var symbol = this._index[p];
  60. if (symbol.is("FILE") || symbol.is("GLOBAL")) continue;
  61. var borrows = symbol.inherits;
  62. for (var i = 0; i < borrows.length; i++) {
  63. var borrowed = this.getSymbol(borrows[i].alias);
  64. if (!borrowed) {
  65. LOG.warn("Can't borrow undocumented "+borrows[i].alias+".");
  66. continue;
  67. }
  68. var borrowAsName = borrows[i].as;
  69. var borrowAsAlias = borrowAsName;
  70. if (!borrowAsName) {
  71. LOG.warn("Malformed @borrow, 'as' is required.");
  72. continue;
  73. }
  74. if (borrowAsName.length > symbol.alias.length && borrowAsName.indexOf(symbol.alias) == 0) {
  75. borrowAsName = borrowAsName.replace(borrowed.alias, "")
  76. }
  77. else {
  78. var joiner = "";
  79. if (borrowAsName.charAt(0) != "#") joiner = ".";
  80. borrowAsAlias = borrowed.alias + joiner + borrowAsName;
  81. }
  82. borrowAsName = borrowAsName.replace(/^[#.]/, "");
  83. if (this.hasSymbol(borrowAsAlias)) continue;
  84. var clone = borrowed.clone();
  85. clone.name = borrowAsName;
  86. clone.alias = borrowAsAlias;
  87. this.addSymbol(clone);
  88. }
  89. }
  90. }
  91. JSDOC.SymbolSet.prototype.resolveMemberOf = function() {
  92. for (var p in this._index) {
  93. var symbol = this.getSymbol(p);
  94. if (symbol.is("FILE") || symbol.is("GLOBAL")) continue;
  95. // the memberOf value was provided in the @memberOf tag
  96. else if (symbol.memberOf) {
  97. var parts = symbol.alias.match(new RegExp("^("+symbol.memberOf+"[.#-])(.+)$"));
  98. // like foo.bar is a memberOf foo
  99. if (parts) {
  100. symbol.memberOf = parts[1];
  101. symbol.name = parts[2];
  102. }
  103. // like bar is a memberOf foo
  104. else {
  105. var joiner = symbol.memberOf.charAt(symbol.memberOf.length-1);
  106. if (!/[.#-]/.test(joiner)) symbol.memberOf += ".";
  107. this.renameSymbol(p, symbol.memberOf + symbol.name);
  108. }
  109. }
  110. // the memberOf must be calculated
  111. else {
  112. var parts = symbol.alias.match(/^(.*[.#-])([^.#-]+)$/);
  113. if (parts) {
  114. symbol.memberOf = parts[1];
  115. symbol.name = parts[2];
  116. }
  117. }
  118. // set isStatic, isInner
  119. if (symbol.memberOf) {
  120. switch (symbol.memberOf.charAt(symbol.memberOf.length-1)) {
  121. case '#' :
  122. symbol.isStatic = false;
  123. symbol.isInner = false;
  124. break;
  125. case '.' :
  126. symbol.isStatic = true;
  127. symbol.isInner = false;
  128. break;
  129. case '-' :
  130. symbol.isStatic = false;
  131. symbol.isInner = true;
  132. break;
  133. }
  134. }
  135. // unowned methods and fields belong to the global object
  136. if (!symbol.is("CONSTRUCTOR") && !symbol.isNamespace && symbol.memberOf == "") {
  137. symbol.memberOf = "_global_";
  138. }
  139. // clean up
  140. if (symbol.memberOf.match(/[.#-]$/)) {
  141. symbol.memberOf = symbol.memberOf.substr(0, symbol.memberOf.length-1);
  142. }
  143. // add to parent's methods or properties list
  144. if (symbol.memberOf) {
  145. var container = this.getSymbol(symbol.memberOf);
  146. if (!container) {
  147. if (JSDOC.Lang.isBuiltin(symbol.memberOf)) container = JSDOC.Parser.addBuiltin(symbol.memberOf);
  148. else {
  149. LOG.warn("Can't document "+symbol.name +" as a member of undocumented symbol "+symbol.memberOf+".");
  150. }
  151. }
  152. if (container) container.addMember(symbol);
  153. }
  154. }
  155. }
  156. JSDOC.SymbolSet.prototype.resolveAugments = function() {
  157. for (var p in this._index) {
  158. var symbol = this.getSymbol(p);
  159. if (symbol.alias == "_global_" || symbol.is("FILE")) continue;
  160. JSDOC.SymbolSet.prototype.walk.apply(this, [symbol]);
  161. }
  162. }
  163. JSDOC.SymbolSet.prototype.walk = function(symbol) {
  164. var augments = symbol.augments;
  165. for(var i = 0; i < augments.length; i++) {
  166. var contributer = this.getSymbol(augments[i]);
  167. if (contributer) {
  168. if (contributer.augments.length) {
  169. JSDOC.SymbolSet.prototype.walk.apply(this, [contributer]);
  170. }
  171. symbol.inheritsFrom.push(contributer.alias);
  172. if (!isUnique(symbol.inheritsFrom)) {
  173. //LOG.warn("Can't resolve augments: Circular reference: "+symbol.alias+" inherits from "+contributer.alias+" more than once.");
  174. }
  175. else {
  176. var cmethods = contributer.methods;
  177. var cproperties = contributer.properties;
  178. for (var ci = 0, cl = cmethods.length; ci < cl; ci++)
  179. symbol.inherit(cmethods[ci]);
  180. for (var ci = 0, cl = cproperties.length; ci < cl; ci++)
  181. symbol.inherit(cproperties[ci]);
  182. }
  183. }
  184. else LOG.warn("Can't augment contributer: "+augments[i]+", not found.");
  185. }
  186. }