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