JSDOC/Scope.js
[gnome.introspection-doc-generator] / JSDOC / Scope.js
1 //<Script type="text/javascript">
2
3 /**
4 * Scope stuff
5
6 * // FIXME - I need this to do next() without doccomments..
7 */
8
9 Identifier = imports.Identifier.Identifier
10 XObject = imports.XObject.XObject; 
11
12
13 function Scope(braceN, parent, startTokN, lastIdent, token)
14 {
15     if (lastIdent.length) {
16        //  println("NEW SCOPE: " + lastIdent);
17     }
18     
19     this.braceN = braceN
20     this.parent = parent;
21     this.id = startTokN;
22     this.identifiers = { };
23     this.subScopes = [];
24     this.hints = { };
25     this.ident = lastIdent;
26     this.gid = Scope.gid++;
27     
28     //print("ADD SCOPE(" + this.gid + ") TO "+ (parent ? this.parent.gid : 'TOP') + ' : ' + 
29     //    (token ? token.toString() : ''));
30     
31     if (parent) {
32         this.parent.subScopes.push(this);
33     } 
34     
35 }
36
37
38
39
40
41
42
43 Scope.prototype = {
44     
45     id : 0,
46     braceN : -1,
47     parent : false,
48     subScopes : false,
49     identifiers : false,  // map of identifiers to {Identifier} objects
50     hints: false, 
51     mungeM : true, 
52     ident: '',
53     
54     munged : false,
55     protectedVars : {}, // only used by to parent..
56     declareIdentifier : function(symbol, token) {
57         
58         print("SCOPE : " + this.gid +  " :SYM: " + symbol + " " + token.toString()+"");
59         
60         if (typeof(this.identifiers[symbol])== 'undefined') {
61             
62             this.identifiers[symbol] =  new Identifier(symbol, this);
63             
64         }
65         if (typeof(token) != 'undefined') { // shoudl this happen?
66             token.identifier = this.identifiers[symbol];
67             
68         }
69         if (this.braceN < 0) {
70                 // then it's global... 
71                 this.identifiers[symbol].toMunge  = false;
72         }
73          
74         
75         this.addToParentScope(symbol);
76         return this.identifiers[symbol];
77     },
78     getIdentifier : function(symbol, token) {
79         if (typeof(this.identifiers[symbol])== 'undefined') {
80             if (['String', 'Date'].indexOf(symbol)> -1) {
81                 return false;
82             }
83             
84             //print("SCOPE : " + this.gid +" = SYMBOL NOT FOUND?" + token.toString());
85             return false;
86         }
87          //print("SCOPE : " + this.gid +" = FOUND:" + token.toString());
88         return this.identifiers[symbol];
89     },
90     
91     addHint : function(varName, varType) {
92         this.hint[varName] = varType;
93     },
94     preventMunging : function() {
95         this.mungeM = false;
96     },
97
98     usedsymcache : false,
99     
100     getUsedSymbols : function() {
101         
102         var result = [];
103        // if (this.usedsymcache !== false) {
104         //    return this.usedsymcache;
105         //}
106         
107         var idents = this.identifiers;
108         for(var i in idents) { 
109             //println('<b>'+i+'</b>='+typeof(idents[i]) +'<br/>');
110             var identifier = this.identifiers[i];
111             var mungedValue = identifier.mungedValue
112             if (!mungedValue.length) {
113                 //println(identifier.toSource());
114                 mungedValue = identifier.name;
115             }
116             result.push(mungedValue);
117         }
118         //println("Symbols for ("+ this.id +"): <B>" + result.join(',') + "</B><BR/>");
119         //this.usedsymcache = result;
120         return result;
121     },
122
123     getAllUsedSymbols :function() {
124         var result = this.getUsedSymbols();
125         var scope = this.parent;
126         while (scope !== false) {
127             //println("addused:"+scope.id);
128             result = result.concat(scope.getUsedSymbols());
129             scope = scope.parent;
130         }
131          //println("Done - addused");
132         return result;
133     },
134     /** - we need to register short vairalbes so they never get munged into.. */
135     addToParentScope: function(ident) 
136     {
137         if (ident.length > 2) {
138             return;
139         }
140         var scope = this.parent;
141         while (scope !== false) {
142             //println("addused:"+scope.id);
143             if (!scope.parent) {
144                 scope.protectedVars[ident] = true;
145             }
146             scope = scope.parent;
147         }
148         
149     },
150     isProtectedVar: function(ident)
151     {
152         if (ident.length > 2) {
153             return false;
154         }
155         var scope = this.parent;
156         while (scope !== false) {
157             //println("addused:"+scope.id);
158             if (!scope.parent) {
159                 if (typeof(scope.protectedVars[ident])  != 'undefined') return true;
160             }
161             scope = scope.parent;
162         }
163         return false;
164     },
165     
166     /**
167      * set's all the munged values on the identifiers.
168      * 
169      * 
170      */
171
172     munge :function() 
173     {
174
175         if (!this.mungeM) {
176             // Stop right here if this scope was flagged as unsafe for munging.
177            // println("MUNGE: SKIP -  Scope" + this.id+"</BR>");
178             return;
179         }
180         if (this.munged) {
181             return;
182         }
183         
184
185         
186         
187         var pickFromSet = 1;
188
189         // Do not munge symbols in the global scope!
190         if (this.parent) {
191             
192             var all = [];
193             for (var ii in this.identifiers) {
194                 all.push(ii);
195             }
196             //print("MUNGE: " + all.join(', '));
197             
198             //println("MUNGE: Building FreeSyms:" + this.id+"</BR>");
199             
200             var freeSymbols = [];
201             var sy = this.getAllUsedSymbols();
202             
203             var addSyms=function(batch)
204             {
205                 for(var i =0;i<batch.length;i++) {
206                     if (sy.indexOf(batch[i]) > -1) {
207                         continue;
208                     }
209                     freeSymbols.push(batch[i]);
210                 }
211             }
212              
213             addSyms(Scope.ones); 
214              
215             var repsym = '';
216             //println(freeSymbols.toSource());
217             
218             //println("MUNGE: Replacing " + this.id+"</BR>");
219             for (var i in  this.identifiers) {
220                 
221                 // is the identifer in the global scope!?!!?
222                 
223                 
224                 if (!this.identifiers[i].toMunge) {
225                     //print("SKIP toMunge==false : " + i)
226                     continue;
227                 }
228                 
229                 if (this.isProtectedVar(i)) {
230                     //print("SKIP PROTECTED: " + i)
231                     continue; // 
232                 }
233                 
234                 
235                 
236                 //if (this.identifiers[i].constructor !=  Identifier) {
237                 //    print("SKIP NOT IDENTIFIER : " + i)
238                 //    continue;
239                // }
240                // println("IDENT:" +i+'</BR>');
241                 
242                 if (!repsym.length) {
243                     if (!freeSymbols.length) {
244                         addSyms(Scope.twos); 
245                     }
246                     repsym = freeSymbols.shift(); // pop off beginngin???
247                 }
248                 
249                 var identifier = this.identifiers[i]; 
250                 //println(typeof(identifier.name));
251                 var mungedValue = identifier.name; 
252                 
253                 //println([     repsym,mungedValue ]);
254                 
255                 if (this.mungeM && repsym.length < mungedValue.length) {
256                     //print("REPLACE:"+ mungedValue +" with " + repsym );    
257                     mungedValue = repsym;
258                     repsym = '';
259                 }
260                 
261                 identifier.mungedValue =  mungedValue;
262             }
263             //println("MUNGE: Done " + this.id+"</BR>");
264         }
265         this.munged = true;
266         //println("Doing sub scopes");
267         for (var j = 0; j < this.subScopes.length; j++) {
268             var ss = this.subScopes[j];
269             ss.munge();
270         }
271     }
272  
273
274 };
275
276
277
278
279
280 XObject.extend(Scope, {
281     
282     builtin : ["NaN","top"],
283     skips : [  'as', 'is', 'do', 'if', 'in', 'for', 'int', 'new', 'try', 'use', 'var', "NaN","top"],
284      
285     ones : [],
286     twos : [],
287     threes : [],
288     init : function () {
289         /* cache it later?
290         if (File.exists('/tmp/var_list_ones.js')) {
291             eval("JSDOC.Scope.ones = " + File.read('/tmp/var_list_ones.js'));
292             eval("JSDOC.Scope.twos = " + File.read('/tmp/var_twos_ones.js'));
293             eval("JSDOC.Scope.threes = " + File.read('/tmp/var_threes_ones.js'));
294         }
295         */
296         this.ones = 'A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'.split(',');
297         var a = this.ones;
298         var n = a.concat( '0,1,2,3,4,5,6,7,8,9'.split(','));
299         for(var i = 0; i < a.length; i++) {
300             for(var j = 0; j < n.length; j++) {
301                 var tw = a[i] + n[j];
302                 if (this.skips.indexOf(tw) < 0) {
303                     this.twos.push(tw);
304                 }
305                     
306                 /*
307                 for(var k = 0; k < n.length; k++) {
308                     var thr = a[i] + n[j] + n[k];
309                     //println("thr="+ thr + ":iOf="+this.skips.indexOf(thr) );
310                     if (this.skips.indexOf(thr)  < 0) {
311                         //println("+"+thr);
312                         this.threes.push(thr);
313                        }
314                     
315                 }
316                 */
317             }
318         }
319         //println("done creating var list");
320         //println("threes="+ this.threes.toSource());
321         //throw "DONE";
322         
323        
324     }
325 })
326 // init the scope constants..
327 Scope.init();
328 Scope.gid = 0;