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