| 1 | if (typeof JSDOC == "undefined") JSDOC = {}; |
| 2 | |
| 3 | /** |
| 4 | @namespace |
| 5 | @requires JSDOC.Walker |
| 6 | @requires JSDOC.Symbol |
| 7 | @requires JSDOC.DocComment |
| 8 | */ |
| 9 | JSDOC.Parser = { |
| 10 | conf: { |
| 11 | ignoreCode: JSDOC.opt.n, |
| 12 | ignoreAnonymous: true, // factory: true |
| 13 | treatUnderscoredAsPrivate: true, // factory: true |
| 14 | explain: false // factory: false |
| 15 | }, |
| 16 | |
| 17 | addSymbol: function(symbol) { |
| 18 | |
| 19 | if (JSDOC.Parser.rename) { |
| 20 | for (var n in JSDOC.Parser.rename) { |
| 21 | if (symbol.alias.indexOf(n) == 0) { |
| 22 | if (symbol.name == symbol.alias) { |
| 23 | symbol.name = symbol.name.replace(n, JSDOC.Parser.rename[n]); |
| 24 | } |
| 25 | symbol.alias = symbol.alias.replace(n, JSDOC.Parser.rename[n]); |
| 26 | } |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | if (JSDOC.opt.S) { |
| 31 | if (typeof JSDOC.Parser.secureModules == "undefined") JSDOC.Parser.secureModules = {}; |
| 32 | if (/^exports\./.test(symbol.alias)) { |
| 33 | symbol.srcFile.match(/(^|[\\\/])([^\\\/]+)\.js/i); |
| 34 | var fileNS = RegExp.$2; |
| 35 | |
| 36 | // need to create the namespace associated with this file first |
| 37 | if (!JSDOC.Parser.secureModules[fileNS]) { |
| 38 | JSDOC.Parser.secureModules[fileNS] = 1; |
| 39 | var nsSymbol = new JSDOC.Symbol(fileNS, [], "GLOBAL", new JSDOC.DocComment("")); |
| 40 | nsSymbol.isNamespace = true; |
| 41 | nsSymbol.srcFile = ""; |
| 42 | nsSymbol.isPrivate = false; |
| 43 | nsSymbol.srcFile = symbol.srcFile; |
| 44 | nsSymbol.desc = (JSDOC.Parser.symbols.getSymbol(symbol.srcFile) || {desc: ""}).desc; |
| 45 | JSDOC.Parser.addSymbol(nsSymbol); |
| 46 | } |
| 47 | |
| 48 | symbol.alias = symbol.alias.replace(/^exports\./, fileNS + '.'); |
| 49 | symbol.name = symbol.name.replace(/^exports\./, ''); |
| 50 | symbol.memberOf = fileNS; |
| 51 | symbol.isStatic = true; |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | // if a symbol alias is documented more than once the first one with the user docs wins |
| 56 | if (JSDOC.Parser.symbols.hasSymbol(symbol.alias)) { |
| 57 | var oldSymbol = JSDOC.Parser.symbols.getSymbol(symbol.alias); |
| 58 | if (oldSymbol.comment.isUserComment) { |
| 59 | if (JSDOC.opt.m) return; |
| 60 | if (symbol.comment.isUserComment) { // old and new are both documented |
| 61 | LOG.warn("The symbol '"+symbol.alias+"' is documented more than once."); |
| 62 | return; |
| 63 | } |
| 64 | else { // old is documented but new isn't |
| 65 | return; |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | // we don't document anonymous things |
| 71 | if (JSDOC.Parser.conf.ignoreAnonymous && symbol.name.match(/\$anonymous\b/)) return; |
| 72 | |
| 73 | // uderscored things may be treated as if they were marked private, this cascades |
| 74 | if (JSDOC.Parser.conf.treatUnderscoredAsPrivate && symbol.name.match(/[.#-]_[^.#-]+$/)) { |
| 75 | if (!symbol.comment.getTag("public").length > 0) symbol.isPrivate = true; |
| 76 | } |
| 77 | |
| 78 | // -p flag is required to document private things |
| 79 | if (!JSDOC.opt.p && symbol.isPrivate) return; // issue #161 fixed by mcbain.asm |
| 80 | |
| 81 | // ignored things are not documented, this doesn't cascade |
| 82 | if (symbol.isIgnored) return; |
| 83 | JSDOC.Parser.symbols.addSymbol(symbol); |
| 84 | }, |
| 85 | |
| 86 | addBuiltin: function(name) { |
| 87 | var builtin = new JSDOC.Symbol(name, [], "CONSTRUCTOR", new JSDOC.DocComment("")); |
| 88 | builtin.isNamespace = true; |
| 89 | builtin.srcFile = ""; |
| 90 | builtin.isPrivate = false; |
| 91 | JSDOC.Parser.addSymbol(builtin); |
| 92 | return builtin; |
| 93 | }, |
| 94 | |
| 95 | init: function() { |
| 96 | JSDOC.Parser.symbols = new JSDOC.SymbolSet(); |
| 97 | JSDOC.Parser.walker = new JSDOC.Walker(); |
| 98 | }, |
| 99 | |
| 100 | finish: function() { |
| 101 | JSDOC.Parser.symbols.relate(); |
| 102 | |
| 103 | // make a litle report about what was found |
| 104 | if (JSDOC.Parser.conf.explain) { |
| 105 | var symbols = JSDOC.Parser.symbols.toArray(); |
| 106 | var srcFile = ""; |
| 107 | for (var i = 0, l = symbols.length; i < l; i++) { |
| 108 | var symbol = symbols[i]; |
| 109 | if (srcFile != symbol.srcFile) { |
| 110 | srcFile = symbol.srcFile; |
| 111 | print("\n"+srcFile+"\n-------------------"); |
| 112 | } |
| 113 | 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); |
| 114 | } |
| 115 | print("-------------------\n"); |
| 116 | } |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | JSDOC.Parser.parse = function(/**JSDOC.TokenStream*/ts, /**String*/srcFile) { |
| 121 | JSDOC.Symbol.srcFile = (srcFile || ""); |
| 122 | JSDOC.DocComment.shared = ""; // shared comments don't cross file boundaries |
| 123 | |
| 124 | if (!JSDOC.Parser.walker) JSDOC.Parser.init(); |
| 125 | JSDOC.Parser.walker.walk(ts); // adds to our symbols |
| 126 | |
| 127 | // filter symbols by option |
| 128 | for (var p = JSDOC.Parser.symbols._index.first(); p; p = JSDOC.Parser.symbols._index.next()) { |
| 129 | var symbol = p.value; |
| 130 | |
| 131 | if (!symbol) continue; |
| 132 | |
| 133 | if (symbol.is("FILE") || symbol.is("GLOBAL")) { |
| 134 | continue; |
| 135 | } |
| 136 | else if (!JSDOC.opt.a && !symbol.comment.isUserComment) { |
| 137 | JSDOC.Parser.symbols.deleteSymbol(symbol.alias); |
| 138 | } |
| 139 | |
| 140 | if (/#$/.test(symbol.alias)) { // we don't document prototypes |
| 141 | JSDOC.Parser.symbols.deleteSymbol(symbol.alias); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | return JSDOC.Parser.symbols.toArray(); |
| 146 | } |