fixes
[oweals/gnunet.git] / src / monkey / seaspider / org / gnunet / seaspider / ExpressionExtractorVisitor.java
1 package org.gnunet.seaspider;
2
3 import org.gnunet.seaspider.parser.nodes.ANDExpression;
4 import org.gnunet.seaspider.parser.nodes.AdditiveExpression;
5 import org.gnunet.seaspider.parser.nodes.ArgumentExpressionList;
6 import org.gnunet.seaspider.parser.nodes.AssignmentExpression;
7 import org.gnunet.seaspider.parser.nodes.AssignmentOperator;
8 import org.gnunet.seaspider.parser.nodes.CastExpression;
9 import org.gnunet.seaspider.parser.nodes.CompoundStatement;
10 import org.gnunet.seaspider.parser.nodes.ConditionalExpression;
11 import org.gnunet.seaspider.parser.nodes.ConstantExpression;
12 import org.gnunet.seaspider.parser.nodes.DoWhileStatement;
13 import org.gnunet.seaspider.parser.nodes.EqualityExpression;
14 import org.gnunet.seaspider.parser.nodes.ExclusiveORExpression;
15 import org.gnunet.seaspider.parser.nodes.Expression;
16 import org.gnunet.seaspider.parser.nodes.ExpressionStatement;
17 import org.gnunet.seaspider.parser.nodes.ForStatement;
18 import org.gnunet.seaspider.parser.nodes.FunctionDeclaration;
19 import org.gnunet.seaspider.parser.nodes.IfStatement;
20 import org.gnunet.seaspider.parser.nodes.InclusiveORExpression;
21 import org.gnunet.seaspider.parser.nodes.InitDeclarator;
22 import org.gnunet.seaspider.parser.nodes.InitDeclaratorList;
23 import org.gnunet.seaspider.parser.nodes.Initializer;
24 import org.gnunet.seaspider.parser.nodes.InitializerList;
25 import org.gnunet.seaspider.parser.nodes.JumpStatement;
26 import org.gnunet.seaspider.parser.nodes.LogicalANDExpression;
27 import org.gnunet.seaspider.parser.nodes.LogicalORExpression;
28 import org.gnunet.seaspider.parser.nodes.MultiplicativeExpression;
29 import org.gnunet.seaspider.parser.nodes.Node;
30 import org.gnunet.seaspider.parser.nodes.NodeChoice;
31 import org.gnunet.seaspider.parser.nodes.NodeSequence;
32 import org.gnunet.seaspider.parser.nodes.NodeToken;
33 import org.gnunet.seaspider.parser.nodes.ParameterDeclaration;
34 import org.gnunet.seaspider.parser.nodes.PostfixExpression;
35 import org.gnunet.seaspider.parser.nodes.PrimaryExpression;
36 import org.gnunet.seaspider.parser.nodes.RelationalExpression;
37 import org.gnunet.seaspider.parser.nodes.ShiftExpression;
38 import org.gnunet.seaspider.parser.nodes.StructOrUnionSpecifier;
39 import org.gnunet.seaspider.parser.nodes.SwitchStatement;
40 import org.gnunet.seaspider.parser.nodes.TranslationUnit;
41 import org.gnunet.seaspider.parser.nodes.TypeDeclaration;
42 import org.gnunet.seaspider.parser.nodes.UnaryExpression;
43 import org.gnunet.seaspider.parser.nodes.UnaryOperator;
44 import org.gnunet.seaspider.parser.nodes.VariableDeclaration;
45 import org.gnunet.seaspider.parser.nodes.WhileStatement;
46 import org.gnunet.seaspider.parser.visitors.DepthFirstVisitor;
47 import org.grothoff.LineNumberInfo;
48
49 /**
50  * @author grothoff
51  * 
52  */
53 public class ExpressionExtractorVisitor extends DepthFirstVisitor {
54
55         class ExpressionBuilder {
56                 String expression = "";
57
58                 void push(String token) {
59                         expression = expression + token;
60                 }
61
62                 void commit(int line) {
63                         ExpressionDatabaseHandler.insertIntoExpressionTable(filename,
64                                         expression, line, scope_end_line);
65                 }
66
67         }
68
69         final String filename;
70
71         ExpressionBuilder current_expression;
72
73         int scope_end_line;
74
75         boolean operator;
76
77         boolean skip_mode = true;
78
79         /**
80          * 
81          */
82         public ExpressionExtractorVisitor(String filename) {
83                 this.filename = filename;
84         }
85
86         public void visit(TranslationUnit n) {
87                 LineNumberInfo lin = LineNumberInfo.get(n);
88                 scope_end_line = lin.lineEnd;
89                 n.f0.accept(this);
90                 assert scope_end_line == lin.lineEnd;
91         }
92
93         public void visit(NodeToken n) {
94                 if (skip_mode)
95                         return;
96                 current_expression.push(n.tokenImage);
97         }
98
99         public void visit(StructOrUnionSpecifier n) {
100                 // do nothing -- skip!
101         }
102
103         public void visit(TypeDeclaration n) {
104                 // do nothing -- skip!
105         }
106
107         public void visit(InitDeclaratorList n) {
108                 assert skip_mode == true;
109                 super.visit(n);
110                 assert skip_mode == true;
111         }
112
113         public void visit(Initializer n) {
114                 assert skip_mode == true;
115                 if (n.f0.which == 0) {
116                         boolean old_mode = skip_mode;
117                         skip_mode = false;
118                         ExpressionBuilder old = current_expression;
119                         current_expression = new ExpressionBuilder();
120                         n.f0.accept(this);
121                         if (old != null) {
122                                 old.push(current_expression.expression);
123                                 LineNumberInfo lin = LineNumberInfo.get(n);
124                                 old.commit(lin.lineEnd);
125                         }
126                         current_expression = old;
127                         skip_mode = old_mode;
128                 } else {
129                         super.visit(n);
130                 }
131                 assert skip_mode == true;
132         }
133
134         public void visit(InitializerList n) {
135                 assert skip_mode == true;
136                 super.visit(n);
137                 assert skip_mode == true;
138         }
139
140         public void visit(VariableDeclaration n) {
141                 assert skip_mode == true;
142                 super.visit(n);
143         }
144
145         public void visit(FunctionDeclaration n) {
146                 if (n.f5.which == 0)
147                         return; // no body
148                 int old_scope = scope_end_line;
149                 LineNumberInfo lin = LineNumberInfo.get(n);
150                 scope_end_line = lin.lineEnd;
151                 n.f3.accept(this);
152                 n.f5.accept(this);
153                 assert scope_end_line == lin.lineEnd;
154                 scope_end_line = old_scope;
155         }
156
157         public void visit(ParameterDeclaration n) {
158                 skip_mode = false;
159                 assert current_expression == null;
160                 if (n.f1.present()) {
161                         NodeSequence ns = (NodeSequence) n.f1.node;
162                         Node var = ns.elementAt(0);
163                         current_expression = new ExpressionBuilder();
164                         var.accept(this);
165                         LineNumberInfo lin = LineNumberInfo.get(var);
166                         current_expression.commit(lin.lineEnd);
167                 }
168                 current_expression = null;
169                 skip_mode = true;
170         }
171
172         public void visit(InitDeclarator n) {
173                 skip_mode = false;
174                 assert current_expression == null;
175                 current_expression = new ExpressionBuilder();
176                 n.f0.accept(this);
177                 current_expression = null;
178                 skip_mode = true;
179                 n.f2.accept(this);
180         }
181
182         public void visit(ExpressionStatement n) {
183                 if (!n.f0.present())
184                         return;
185                 assert current_expression == null;
186                 skip_mode = false;
187                 current_expression = new ExpressionBuilder();
188                 n.f0.accept(this);
189                 LineNumberInfo lin = LineNumberInfo.get(n);
190                 current_expression.commit(lin.lineEnd);
191                 current_expression = null;
192                 skip_mode = true;
193         }
194
195         public void visit(CompoundStatement n) {
196                 assert current_expression == null;
197                 assert skip_mode == true;
198                 int old_end = scope_end_line;
199                 scope_end_line = n.f2.endLine;
200                 n.f1.accept(this);
201                 scope_end_line = old_end;
202         }
203
204         public void visit(SwitchStatement n) {
205                 assert current_expression == null;
206                 skip_mode = false;
207                 current_expression = new ExpressionBuilder();
208                 n.f2.accept(this);
209                 current_expression.commit(n.f0.endLine);
210                 skip_mode = true;
211                 current_expression = null;
212                 n.f4.accept(this);
213         }
214
215         public void visit(IfStatement n) {
216                 assert current_expression == null;
217                 skip_mode = false;
218                 current_expression = new ExpressionBuilder();
219                 n.f2.accept(this);
220                 current_expression.commit(n.f0.endLine);
221                 skip_mode = true;
222                 current_expression = null;
223                 n.f4.accept(this);
224                 n.f5.accept(this);
225         }
226
227         public void visit(WhileStatement n) {
228                 assert current_expression == null;
229                 skip_mode = false;
230                 current_expression = new ExpressionBuilder();
231                 n.f2.accept(this);
232                 current_expression.commit(n.f0.endLine);
233                 skip_mode = true;
234                 current_expression = null;
235                 n.f4.accept(this);
236         }
237
238         public void visit(DoWhileStatement n) {
239                 assert current_expression == null;
240                 skip_mode = false;
241                 current_expression = new ExpressionBuilder();
242                 n.f4.accept(this);
243                 current_expression.commit(n.f6.endLine);
244                 skip_mode = true;
245                 current_expression = null;
246                 n.f1.accept(this);
247         }
248
249         public void visit(ForStatement n) {
250                 assert current_expression == null;
251                 skip_mode = false;
252                 int old_scope = scope_end_line;
253                 LineNumberInfo lin = LineNumberInfo.get(n);
254                 scope_end_line = lin.lineEnd;
255                 if (n.f2.present()) {
256                         current_expression = new ExpressionBuilder();
257                         n.f2.accept(this);
258                         current_expression.commit(n.f3.endLine);
259                 }
260                 if (n.f4.present()) {
261                         current_expression = new ExpressionBuilder();
262                         n.f4.accept(this);
263                         current_expression.commit(n.f5.endLine);
264                 }
265                 if (n.f6.present()) {
266                         current_expression = new ExpressionBuilder();
267                         n.f6.accept(this);
268                         current_expression.commit(n.f7.endLine);
269                 }
270                 skip_mode = true;
271                 current_expression = null;
272                 n.f8.accept(this);
273                 scope_end_line = old_scope;
274         }
275
276         public void visit(JumpStatement n) {
277                 if (n.f0.which != 3)
278                         return;
279                 NodeSequence ns = (NodeSequence) n.f0.choice;
280                 assert current_expression == null;
281                 skip_mode = false;
282                 current_expression = new ExpressionBuilder();
283                 ns.elementAt(1).accept(this);
284                 LineNumberInfo lin = LineNumberInfo.get(n);
285                 current_expression.commit(lin.lineEnd);
286                 current_expression = null;
287                 skip_mode = true;
288         }
289
290         public void visit(Expression n) {
291                 ExpressionBuilder old = current_expression;
292                 current_expression = new ExpressionBuilder();
293                 n.f0.accept(this);
294                 for (int i = 0; i < n.f1.size(); i++) {
295                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
296                         current_expression = new ExpressionBuilder();
297                         ns.elementAt(1).accept(this);
298                 }
299                 old.push(current_expression.expression);
300                 current_expression = old;
301         }
302
303         public void visit(AssignmentOperator n) {
304                 operator = true;
305                 super.visit(n);
306                 operator = false;
307         }
308
309         public void visit(ConditionalExpression n) {
310                 ExpressionBuilder old = current_expression;
311                 current_expression = new ExpressionBuilder();
312                 n.f0.accept(this);
313                 old.push(current_expression.expression);
314                 if (n.f1.present()) {
315                         LineNumberInfo lin = LineNumberInfo.get(n);
316                         NodeSequence ns = (NodeSequence) n.f1.node;
317                         current_expression = new ExpressionBuilder();
318                         ns.elementAt(1).accept(this);
319                         current_expression.commit(lin.lineEnd);
320                         old.push("?");
321                         old.push(current_expression.expression);
322                         current_expression = new ExpressionBuilder();
323                         ns.elementAt(3).accept(this);
324                         current_expression.commit(lin.lineEnd);
325                         old.push(":");
326                         old.push(current_expression.expression);
327                         old.commit(lin.lineEnd);
328                 }
329                 current_expression = old;
330         }
331
332         public void visit(ConstantExpression n) {
333                 /* skip */
334         }
335
336         public void visit(LogicalORExpression n) {
337                 assert skip_mode == false;
338                 ExpressionBuilder old = current_expression;
339                 current_expression = new ExpressionBuilder();
340                 n.f0.accept(this);
341                 if (n.f1.present()) {
342                         LineNumberInfo lin = LineNumberInfo.get(n);
343                         current_expression.commit(lin.lineEnd);
344                         operator = true;
345                         NodeSequence ns = (NodeSequence) n.f1.node;
346                         ns.nodes.get(0).accept(this);
347                         operator = false;
348                         old.push(current_expression.expression);                        
349                         current_expression = new ExpressionBuilder();                   
350                         ns.nodes.get(1).accept(this);
351                         current_expression.commit(lin.lineEnd);
352                 }
353                 old.push(current_expression.expression);
354                 current_expression = old;
355         }
356
357         public void visit(LogicalANDExpression n) {
358                 assert skip_mode == false;
359                 ExpressionBuilder old = current_expression;
360                 current_expression = new ExpressionBuilder();
361                 n.f0.accept(this);
362                 if (n.f1.present()) {
363                         LineNumberInfo lin = LineNumberInfo.get(n);
364                         current_expression.commit(lin.lineEnd);
365                         operator = true;
366                         NodeSequence ns = (NodeSequence) n.f1.node;
367                         ns.nodes.get(0).accept(this);
368                         operator = false;
369                         old.push(current_expression.expression);                        
370                         current_expression = new ExpressionBuilder();                   
371                         ns.nodes.get(1).accept(this);
372                         current_expression.commit(lin.lineEnd);
373                 }
374                 old.push(current_expression.expression);
375                 current_expression = old;
376         }
377
378         public void visit(InclusiveORExpression n) {
379                 assert skip_mode == false;
380                 ExpressionBuilder old = current_expression;
381                 current_expression = new ExpressionBuilder();
382                 n.f0.accept(this);
383                 if (n.f1.present()) {
384                         operator = true;
385                         NodeSequence ns = (NodeSequence) n.f1.node;
386                         ns.nodes.get(0).accept(this);
387                         operator = false;
388                         ns.nodes.get(1).accept(this);
389                 }
390                 old.push(current_expression.expression);
391                 current_expression = old;
392         }
393
394         public void visit(ExclusiveORExpression n) {
395                 assert skip_mode == false;
396                 ExpressionBuilder old = current_expression;
397                 current_expression = new ExpressionBuilder();
398                 n.f0.accept(this);
399                 if (n.f1.present()) {
400                         operator = true;
401                         NodeSequence ns = (NodeSequence) n.f1.node;
402                         ns.nodes.get(0).accept(this);
403                         operator = false;
404                         ns.nodes.get(1).accept(this);
405                 }
406                 old.push(current_expression.expression);
407                 current_expression = old;
408         }
409
410         public void visit(ANDExpression n) {
411                 assert skip_mode == false;
412                 ExpressionBuilder old = current_expression;
413                 current_expression = new ExpressionBuilder();
414                 n.f0.accept(this);
415                 if (n.f1.present()) {
416                         operator = true;
417                         NodeSequence ns = (NodeSequence) n.f1.node;
418                         ns.nodes.get(0).accept(this);
419                         operator = false;
420                         ns.nodes.get(1).accept(this);
421                 }
422                 old.push(current_expression.expression);
423                 current_expression = old;
424         }
425
426         // Safey: this function was fixed to commit the right hand side, the
427         // other similar functions still need to be updated accordingly...
428         public void visit(EqualityExpression n) {
429                 assert skip_mode == false;
430                 ExpressionBuilder old = current_expression;
431                 current_expression = new ExpressionBuilder();
432                 n.f0.accept(this);
433                 if (n.f1.present()) {
434                         LineNumberInfo lin = LineNumberInfo.get(n);
435                         current_expression.commit(lin.lineEnd);
436                         operator = true;
437                         NodeSequence ns = (NodeSequence) n.f1.node;
438                         ns.nodes.get(0).accept(this);
439                         operator = false;
440                         old.push(current_expression.expression);
441                         current_expression = new ExpressionBuilder();
442                         ns.nodes.get(1).accept(this);
443                         current_expression.commit(lin.lineEnd);
444                 }
445                 old.push(current_expression.expression);
446                 current_expression = old;
447         }
448
449         public void visit(RelationalExpression n) {
450                 assert skip_mode == false;
451                 ExpressionBuilder old = current_expression;
452                 current_expression = new ExpressionBuilder();
453                 n.f0.accept(this);
454                 if (n.f1.present()) {
455                         operator = true;
456                         NodeSequence ns = (NodeSequence) n.f1.node;
457                         ns.nodes.get(0).accept(this);
458                         operator = false;
459                         ns.nodes.get(1).accept(this);
460                 }
461                 old.push(current_expression.expression);
462                 current_expression = old;
463         }
464
465         public void visit(ShiftExpression n) {
466                 assert skip_mode == false;
467                 ExpressionBuilder old = current_expression;
468                 current_expression = new ExpressionBuilder();
469                 n.f0.accept(this);
470                 if (n.f1.present()) {
471                         operator = true;
472                         NodeSequence ns = (NodeSequence) n.f1.node;
473                         ns.nodes.get(0).accept(this);
474                         operator = false;
475                         ns.nodes.get(1).accept(this);
476                 }
477                 old.push(current_expression.expression);
478                 current_expression = old;
479         }
480
481         public void visit(AdditiveExpression n) {
482                 assert skip_mode == false;
483                 ExpressionBuilder old = current_expression;
484                 current_expression = new ExpressionBuilder();
485                 n.f0.accept(this);
486                 if (n.f1.present()) {
487                         operator = true;
488                         NodeSequence ns = (NodeSequence) n.f1.node;
489                         ns.nodes.get(0).accept(this);
490                         operator = false;
491                         ns.nodes.get(1).accept(this);
492                 }
493                 old.push(current_expression.expression);
494                 current_expression = old;
495         }
496
497         public void visit(MultiplicativeExpression n) {
498                 assert skip_mode == false;
499                 ExpressionBuilder old = current_expression;
500                 current_expression = new ExpressionBuilder();
501                 n.f0.accept(this);
502                 if (n.f1.present()) {
503                         operator = true;
504                         NodeSequence ns = (NodeSequence) n.f1.node;
505                         ns.nodes.get(0).accept(this);
506                         operator = false;
507                         ns.nodes.get(1).accept(this);
508                 }
509                 old.push(current_expression.expression);
510                 current_expression = old;
511         }
512
513         public void visit(CastExpression n) {
514                 if (n.f0.which == 1) {
515                         n.f0.accept(this);
516                         return;
517                 }
518                 NodeSequence ns = (NodeSequence) n.f0.choice;
519                 ns.nodes.get(3).accept(this);
520         }
521
522         public void visit(UnaryExpression n) {
523                 if ((n.f0.which == 1) || (n.f0.which == 2)) {
524                         NodeSequence ns = (NodeSequence) n.f0.choice;
525                         ns.nodes.get(1).accept(this);
526                 } else
527                         n.f0.accept(this);
528
529         }
530
531         public void visit(UnaryOperator n) {
532                 operator = true;
533                 n.f0.accept(this);
534                 operator = false;
535         }
536
537         public void visit(PostfixExpression n) {
538                 n.f0.accept(this);
539                 for (int i = 0; i < n.f1.size(); i++) {
540                         NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
541                         switch (nc.which) {
542                         case 0: // []
543                         {
544                                 ExpressionBuilder old = current_expression;
545                                 current_expression = new ExpressionBuilder();
546                                 NodeSequence ns = (NodeSequence) nc.choice;
547                                 ns.elementAt(1).accept(this);
548                                 LineNumberInfo lin = LineNumberInfo.get(n);
549                                 current_expression.commit(lin.colEnd);
550                                 old.push("[");
551                                 old.push(current_expression.expression);
552                                 old.push("]");
553                                 current_expression = old;
554                         }
555                         case 1: // ()
556                         {
557                                 ExpressionBuilder old = current_expression;
558                                 current_expression = new ExpressionBuilder();
559                                 NodeSequence ns = (NodeSequence) nc.choice;
560                                 ns.elementAt(1).accept(this);
561                                 old.push("(");
562                                 old.push(current_expression.expression);
563                                 old.push(")");
564                                 current_expression = old;
565                         }
566                                 break;
567                         case 2: // .
568                         case 3: // ->
569                         {
570                                 ExpressionBuilder old = current_expression;
571                                 LineNumberInfo lin = LineNumberInfo.get(n);
572                                 old.commit(lin.lineEnd);
573                                 current_expression = new ExpressionBuilder();
574                                 NodeSequence ns = (NodeSequence) nc.choice;
575                                 ns.elementAt(1).accept(this);
576                                 if (nc.which == 2)
577                                         old.push(".");
578                                 else
579                                         old.push("->");
580                                 old.push(current_expression.expression);
581                                 current_expression = old;
582                         }
583                                 break;
584                         case 4: // ++
585                         case 5: // --
586                                 /* skip */
587                                 break;
588                         default:
589                                 throw new Error("Oops!");
590                         }
591                 }
592         }
593
594         public void visit(PrimaryExpression n) {
595                 if (n.f0.which == 2) {
596                         ExpressionBuilder old = current_expression;
597                         current_expression = new ExpressionBuilder();
598                         NodeSequence ns = (NodeSequence) n.f0.choice;
599                         ns.elementAt(1).accept(this);
600                         old.push("(");
601                         old.push(current_expression.expression);
602                         old.push(")");
603                         LineNumberInfo lin = LineNumberInfo.get(n);
604                         old.commit(lin.lineEnd);
605                         current_expression = old;
606                 } else
607                         n.f0.accept(this);
608         }
609
610         public void visit(ArgumentExpressionList n) {
611                 ExpressionBuilder old = current_expression;
612                 current_expression = new ExpressionBuilder();
613                 n.f0.accept(this);
614                 old.push(current_expression.expression);
615                 for (int i = 0; i < n.f1.size(); i++) {
616                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
617                         current_expression = new ExpressionBuilder();
618                         ns.elementAt(1).accept(this);
619                         old.push(",");
620                         old.push(current_expression.expression);
621                 }
622                 current_expression = old;
623         }
624
625 }