JSDOC/TokenReader.js
[gnome.introspection-doc-generator] / JSDOC / Scope.vala
1  
2
3 namespace JSDOC 
4 {
5         public int Scope_gid = 0;
6         
7         public class Scope : Object 
8         {
9         
10             int id ;
11                 int braceN ;
12                 public Scope parent;
13                 public Gee.ArrayList<Scope> subScopes;
14                 Gee.HashMap<string,Identifier> identifiers;   // map of identifiers to {Identifier} objects
15                 Gee.HashMap<string,string> hints;
16                 bool mungeM = true;
17                 //ident: '',
18                 
19                 bool munged  = false;
20             Gee.HashMap<string,bool> protectedVars ; // only used by to parent..
21                 Token? token;
22
23                 public Scope(int braceN, Scope? parent, int startTokN, Token? token) // Identifier? lastIdent
24                 {
25                         //if (lastIdent.length) {
26                            //  println("NEW SCOPE: " + lastIdent);
27                         //}
28                 
29                         this.braceN = braceN;
30                         this.parent = parent;
31                         this.id = startTokN;
32                         this.identifiers = new Gee.HashMap<string,Identifier>();
33                         this.subScopes = new Gee.ArrayList<Scope> ();
34                         this.hints = new Gee.HashMap<string,string>();
35                         this.protectedVars = new Gee.HashMap<string,bool>();
36                         //this.ident = lastIdent;
37                         this.id = Scope_gid++;
38                         this.token = token;
39                         //print("ADD SCOPE(" + this.gid + ") TO "+ (parent ? this.parent.gid : 'TOP') + ' : ' + 
40                         //    (token ? token.toString() : ''));
41                 
42                         if (parent != null) {
43                                 this.parent.subScopes.add(this);
44                         } 
45                         Scope.init();
46                 
47                 }
48
49
50
51
52
53
54
55          
56                 /**
57                  * dump the scope to StdOut...
58                  * 
59                  */
60                 void dump (string indent) 
61                 {
62                     //indent = indent || '';
63                     print(
64                         indent +  "Scope: %d\n" +
65                         indent + "Started: %d\n" +
66                         indent + "- idents..: fixme\n"
67                                 , 
68                                 this.id,
69                                 this.token != null ? this.token.line  : -1
70                                 //                   " + XObject.keys(this.identifiers).join(", ") + "
71                     );
72                     foreach(var s in this.subScopes) {
73                            s.dump(indent + " ");
74                     };
75                     
76                     
77                 }
78     
79     
80                 public Identifier declareIdentifier(string symbol, Token token) 
81                 {
82                     
83                     //print("SCOPE : " + this.gid +  " :SYM: " + symbol + " " + token.toString()+"");
84                     
85                     if (!this.identifiers.has_key(symbol)) {
86                         
87                         this.identifiers.set(symbol,   new Identifier(symbol, this));
88                         
89                     }
90                     
91                     //if (typeof(token) != 'undefined') { // shoudl this happen?
92                         token.identifier = this.identifiers.get(symbol);
93                         
94                     //}
95                     if (this.braceN < 0) {
96                             // then it's global... 
97                             this.identifiers[symbol].toMunge  = false;
98                     }
99                      
100                     
101                     this.addToParentScope(symbol);
102                     return this.identifiers.get(symbol);
103                 }
104                 
105                 
106                 
107                 public Identifier? getIdentifier(string symbol, Token token) 
108                 {
109                     if (!this.identifiers.has_key(symbol)) {
110                                 return null;
111                         //if (['String', 'Date'].indexOf(symbol)> -1) {
112                          //   return false;
113                         //}
114                         
115                         //print("SCOPE : " + this.gid +" = SYMBOL NOT FOUND?" + token.toString());
116                         //return n;
117                     }
118                      //print("SCOPE : " + this.gid +" = FOUND:" + token.toString());
119                     return this.identifiers.get(symbol);
120                 }
121                 
122                 public void addHint(string varName, string varType) {
123                 
124                     this.hints.set(varName, varType);
125                 }
126                 public void preventMunging () {
127                     this.mungeM = false;
128                 }
129
130                 //usedsymcache : false,
131                 
132                 public string[] getUsedSymbols () {
133                     
134                     string[] result = {};
135                     
136                    // if (this.usedsymcache !== false) {
137                     //    return this.usedsymcache;
138                     //}
139                     
140                     var idents = this.identifiers;
141                     var iter = idents.map_iterator();
142                     while (iter.next()) {
143                             var i = iter.get_key();
144                         //println('<b>'+i+'</b>='+typeof(idents[i]) +'<br/>');
145                         var identifier = this.identifiers.get(i);
146                         var mungedValue = identifier.mungedValue;
147                         
148                         if (mungedValue.length < 1) {
149                             //println(identifier.toSource());
150                             mungedValue = identifier.name;
151                         }
152                         result += mungedValue;
153                     }
154                     //println("Symbols for ("+ this.id +"): <B>" + result.join(',') + "</B><BR/>");
155                     //this.usedsymcache = result;
156                     return result;
157                 }
158
159                 string[] getAllUsedSymbols() 
160                 {
161                     var result = this.getUsedSymbols();
162                     var scope = this.parent;
163                     while (scope != null) {
164                                 var ps = scope.getUsedSymbols();
165                                 for (var i =0;  i< ps.length; i++) {
166                                         result += ps[i];
167                                 }
168                         scope = scope.parent;
169                     }
170                      //println("Done - addused");
171                     return result;
172                 }
173                 /** - we need to register short vairalbes so they never get munged into.. */
174                 public void addToParentScope(string ident) 
175                 {
176                     if (ident.length > 2) {
177                         return;
178                     }
179                     var scope = this.parent;
180                     while (scope != null) {
181                         //println("addused:"+scope.id);
182                         if (scope.parent != null) {
183                             scope.protectedVars.set(ident, true);
184                         }
185                         scope = scope.parent;
186                     }
187                     
188                 }
189                 public bool isProtectedVar(string ident)
190                 {
191                     if (ident.length > 2) {
192                         return false;
193                     }
194                     var scope = this.parent;
195                     while (scope != null) {
196                         //println("addused:"+scope.id);
197                         if (scope.parent != null) {
198                                 if (scope.protectedVars.has_key(ident)) {
199                                         return true;
200                                         }
201                         }
202                         scope = scope.parent;
203                     }
204                     return false;
205                 }
206                 
207                 
208                 
209                 
210                 /**
211                  * set's all the munged values on the identifiers.
212                  * 
213                  * 
214                  */
215
216                 public void munge() 
217                 {
218
219                     if (!this.mungeM) {
220                         // Stop right here if this scope was flagged as unsafe for munging.
221                        // println("MUNGE: SKIP -  Scope" + this.id+"</BR>");
222                         return;
223                     }
224                     if (this.munged) {
225                         return;
226                     }
227                     
228
229                     
230                     
231                     var pickFromSet = 1;
232
233                     // Do not munge symbols in the global scope!
234                     if (this.parent == null) {
235                                 // same code at bottom... ?? goto::
236                                 this.munged = true;
237                                 //println("Doing sub scopes");
238                                 for (var j = 0; j < this.subScopes.size; j++) {
239                                         this.subScopes.get(j).munge();
240                                         
241                                 }
242                     
243                                 return;
244                         }
245                         
246                     string[] all = {};
247                     var iter = this.identifiers.map_iterator();
248                     while (iter.next()) {
249                         all += iter.get_key();
250                     }
251                     //print("MUNGE: " + all.join(', '));
252                         
253                         //println("MUNGE: Building FreeSyms:" + this.id+"</BR>");
254                         
255                     Gee.ArrayList<string> freeSymbols= new Gee.ArrayList<string>();
256                     
257                     var sy = this.getAllUsedSymbols();
258                         
259                         Scope.array_merge(freeSymbols,Scope.ones); 
260                          
261                     var repsym = "";
262                         //println(freeSymbols.toSource());
263                        
264                         //println("MUNGE: Replacing " + this.id+"</BR>");
265                     iter = this.identifiers.map_iterator();
266                     while (iter.next()) {
267                                 var i = iter.get_key();
268                         
269                         // is the identifer in the global scope!?!!?
270                         
271                         
272                         if (!this.identifiers.get(i).toMunge) {
273                             //print("SKIP toMunge==false : " + i)
274                             continue;
275                         }
276                         
277                         if (this.isProtectedVar(i)) {
278                             //print("SKIP PROTECTED: " + i)
279                             continue; // 
280                         }
281                         
282                         
283                         
284                         //if (this.identifiers[i].constructor !=  Identifier) {
285                         //    print("SKIP NOT IDENTIFIER : " + i)
286                         //    continue;
287                        // }
288                        // println("IDENT:" +i+'</BR>');
289                         
290                         if (repsym.length < 1) {
291                             if (freeSymbols.size < 1) {
292                                 Scope.array_merge(freeSymbols,Scope.twos); 
293                             }
294                             repsym = freeSymbols.remove_at(0); // pop off beginngin???
295                         }
296                         
297                         var identifier = this.identifiers.get(i); 
298                         //println(typeof(identifier.name));
299                         var mungedValue = identifier.name; 
300                         
301                         //println([     repsym,mungedValue ]);
302                         
303                         if (this.mungeM && repsym.length < mungedValue.length) {
304                             //print("REPLACE:"+ mungedValue +" with " + repsym );    
305                             mungedValue = repsym;
306                             repsym = "";
307                         }
308                         
309                         identifier.mungedValue =  mungedValue;
310                     }
311                     //println("MUNGE: Done " + this.id+"</BR>");
312                          
313                         this.munged = true;
314                         //println("Doing sub scopes");
315                         for (var j = 0; j < this.subScopes.size; j++) {
316                                 this.subScopes.get(j).munge();
317                         }
318                 }
319                  
320
321
322                 // ---------------------- static part... --------------------
323
324
325
326                 static void array_merge(Gee.ArrayList<string> fs, string[] toadd) 
327                 {
328                         foreach(var i in toadd) {
329                                 fs.add(i);
330                         }
331                  
332                 }
333                 static bool initialized = false;
334                 public static Gee.ArrayList<string> builtin;
335                 public static Gee.ArrayList<string> skips;
336                          
337                 public static string[] ones;
338                 public static string[] twos;
339         //      static string[] threes : [],
340                 static  void init () 
341                 {
342                         if (Scope.initialized) {
343                                 return;
344                         }
345                         Scope.initialized = true;
346                         Scope.builtin = new Gee.ArrayList<string>(); 
347                         array_merge(Scope.builtin, "NaN,top".split(","));
348                 
349                         Scope.skips =  new Gee.ArrayList<string>(); 
350                         array_merge(Scope.skips, "as,is,do,if,in,for,int,new,try,use,var,NaN,top".split(","));
351                 
352                         Scope.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(",");
353                         var n = "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,0,1,2,3,4,5,6,7,8,9".split(",");
354
355                         string[] twos = {};
356                         for(var i = 0; i < Scope.ones.length; i++) {
357                             for(var j = 0; j < n.length; j++) {
358                                 string tw = Scope.ones[i] + n[j];
359                                 if (Scope.skips.index_of(tw) < 0) {
360                                     twos += tw;
361                                 }
362                                     
363                                 /*
364                                 for(var k = 0; k < n.length; k++) {
365                                     var thr = a[i] + n[j] + n[k];
366                                     //println("thr="+ thr + ":iOf="+this.skips.indexOf(thr) );
367                                     if (this.skips.indexOf(thr)  < 0) {
368                                         //println("+"+thr);
369                                         this.threes.push(thr);
370                                        }
371                                     
372                                 }
373                                 */
374                             }
375                         }
376                         Scope.twos = twos;
377                         //println("done creating var list");
378                         //println("threes="+ this.threes.toSource());
379                         //throw "DONE";
380                         
381                          
382                 }
383         
384         }
385 }
386
387
388