JSDOC/Parser.js
[app.jsdoc] / JSDOC / Parser.js
1 //<script type="text/javascript">
2 XObject      = imports.XObject.XObject;
3
4 Symbol      = imports.Symbol.Symbol;
5 SymbolSet      = imports.SymbolSet.SymbolSet;
6 DocComment  = imports.DocComment.DocComment;
7  /**
8  * @class Parser
9  * @scope JSDOC
10  * Manages and builds the symbolsets by calling walker to create all of the symols
11  */
12 Parser = XObject.define(
13     /**
14      * @constructor
15      * @param {Object} opts The configuration
16      *
17      *
18      */ 
19         
20     function(opts) {
21         
22         XObject.extend(this, opts);
23         
24           
25         this.conf = {
26             loaded : true,
27             //ignoreCode:                 Options.n,
28             ignoreAnonymous:           true, // factory: true
29             treatUnderscoredAsPrivate: true, // factory: true
30             explain:                   false // factory: false
31         };
32         this.symbols = new  SymbolSet();
33         SymbolSet.parser = this;
34         Symbol.parser = this;
35
36
37     },
38     Object,
39     { 
40         // cfg.. document me..
41         DOC : false,
42         docPrivate : false,
43         
44         conf: false, 
45         walker : false, // will be JSDOC.Walker()
46         symbols : false, //will be JSDOC.SymbolSet()
47         
48         
49         
50         filesSymbols : { },
51         
52         /** 
53         * reset the parser..
54         * 
55         */
56         reset : function()
57         {
58             
59            
60              
61             
62         },
63       
64     
65     
66     
67         /**
68          * Parse a token stream.
69          * @param {JSDOC.TokenStream} token stream
70          * @param {String} filename 
71              
72          */
73         
74         
75         parse : function(ts, srcFile) 
76         {
77             
78             
79             
80             // not a nice way to set stuff...
81             
82             Symbol.srcFile = (srcFile || "");
83             DocComment.shared = ""; // shared comments don't cross file boundaries
84             
85            
86             
87             
88             
89             this.filesSymbols[Symbol.srcFile] = new SymbolSet();
90             
91             //Options.LOG.inform("Parser - run walker");
92             this.walker = new  imports.Walker2.Walker2( {
93                 ts : ts,
94                 parser : this
95             });
96             this.walker.buildSymbolTree();
97             
98             
99             
100             //this.walker.walk(ts); // adds to our symbols
101            // throw "done sym tree";
102             //Options.LOG.inform("Parser - checking symbols");
103             // filter symbols by option
104             for (p in this.symbols._index) {
105                 var symbol = this.symbols.getSymbol(p);
106                 
107                // print(JSON.stringify(symbol, null,4));
108                 
109                 if (!symbol) continue;
110                 
111                 if (symbol.isPrivate) {
112                     this.symbols.deleteSymbol(symbol.alias);
113                     continue;
114                 }
115                 
116                 if (symbol.is("FILE") || symbol.is("GLOBAL")) {
117                     continue;
118                 }
119                 //else if (!Options.a && !symbol.comment.isUserComment) {
120                     //print("Deleting Symbols (no a / user comment): " + symbol.alias);
121                     //this.symbols.deleteSymbol(symbol.alias);
122                     //this.filesSymbols[Symbol.srcFile].deleteSymbol(symbol.alias);
123                 //}
124                 
125                 if (/#$/.test(symbol.alias)) { // we don't document prototypes - this should not happen..
126                     // rename the symbol ??
127                     /*if (!this.symbols.getSymbol(symbol.alias.substring(0,symbol.alias.length-1))) {
128                         // rename it..
129                         print("Renaming Symbol (got  a #): " + symbol.alias);
130                         var n = '' + symbol.alias;
131                         this.symbols.renameSymbol( n ,n.substring(0,n-1));
132                         this.filesSymbols[Symbol.srcFile].renameSymbol( n ,n.substring(0,n-1));
133                         continue;
134                     }
135                     */
136                     print("Deleting Symbols (got  a #): " + symbol.alias);
137                     
138                     this.symbols.deleteSymbol(symbol.alias);
139                     this.filesSymbols[Symbol.srcFile].deleteSymbol(symbol.alias);
140                 
141                 }
142             }
143             //print(prettyDump(toQDump(this.filesSymbols[Symbol.srcFile]._index,'{','}')));
144             //print("AfterParse: " + this.symbols.keys().toSource().split(",").join(",\n   "));
145             return this.symbols.toArray();
146         },
147     
148         
149         addSymbol: function(symbol) 
150         {
151             print("+symbol : " + symbol.alias);
152             
153             // if a symbol alias is documented more than once the last one with the user docs wins
154             if (this.symbols.hasSymbol(symbol.alias)) {
155                 var oldSymbol = this.symbols.getSymbol(symbol.alias);
156                 
157                 if (oldSymbol.comment.isUserComment && !oldSymbol.comment.hasTags) {
158                     if (symbol.comment.isUserComment) { // old and new are both documented
159                         this.LOG.warn("The symbol '"+symbol.alias+"' is documented more than once.");
160                     }
161                     else { // old is documented but new isn't
162                         return;
163                     }
164                 }
165             }
166             
167             // we don't document anonymous things
168             if (this.conf.ignoreAnonymous && symbol.name.match(/\$anonymous\b/)) return;
169     
170             // uderscored things may be treated as if they were marked private, this cascades
171             if (this.conf.treatUnderscoredAsPrivate && symbol.name.match(/[.#-]_[^.#-]+$/)) {
172                 symbol.isPrivate = true;
173             }
174             
175             // -p flag is required to document private things
176             if ((symbol.isInner || symbol.isPrivate) && !this.docPrivate) return;
177             
178             // ignored things are not documented, this doesn't cascade
179             if (symbol.isIgnored) return;
180             // add it to the file's list... (for dumping later..)
181             if (Symbol.srcFile) {
182                 this.filesSymbols[Symbol.srcFile].addSymbol(symbol);
183             }
184             
185             this.symbols.addSymbol(symbol);
186         },
187         
188         addBuiltin: function(name)
189         {
190       
191             var builtin = new Symbol(name, [], "CONSTRUCTOR", new DocComment(""));
192             builtin.isNamespace = false;
193             builtin.srcFile = "";
194             builtin.isPrivate = false;
195             this.addSymbol(builtin);
196             return builtin;
197         },
198         
199             
200         finish: function()
201         {
202             this.symbols.relate();              
203             
204             // make a litle report about what was found
205             if (this.conf.explain) {
206                 var symbols = this.symbols.toArray();
207                 var srcFile = "";
208                 for (var i = 0, l = symbols.length; i < l; i++) {
209                     var symbol = symbols[i];
210                     if (srcFile != symbol.srcFile) {
211                         srcFile = symbol.srcFile;
212                         print("\n"+srcFile+"\n-------------------");
213                     }
214                     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);
215                 }
216                 print("-------------------\n");
217             }
218         },
219         /**
220          * return symbols so they can be serialized.
221          */
222         symbolsToObject : function(srcFile)
223         {
224             //this.filesSymbols[srcFile] is a symbolset..
225             return this.filesSymbols[srcFile];
226             
227                 //    Parser.filesSymbols[srcFile]._index
228         }
229     
230     }
231 );