Merge changes I29db4164,I90632cf4
[gigi.git] / util-testing / org / cacert / gigi / localisation / TranslationCollectingVisitor.java
1 package org.cacert.gigi.localisation;
2 import java.lang.reflect.Method;
3
4 import org.eclipse.jdt.internal.compiler.ASTVisitor;
5 import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
6 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
7 import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
8 import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
9 import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
10 import org.eclipse.jdt.internal.compiler.ast.Expression;
11 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
12 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
13 import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
14 import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
15 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
16 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
17 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
18 import org.eclipse.jdt.internal.compiler.util.Util;
19
20 public final class TranslationCollectingVisitor extends ASTVisitor {
21         MethodBinding cm;
22         private CompilationUnitDeclaration unit;
23         TaintSource[] ts;
24         private TranslationCollector translationCollector;
25
26         public TranslationCollectingVisitor(CompilationUnitDeclaration unit,
27                         TaintSource[] target, TranslationCollector c) {
28                 this.unit = unit;
29                 ts = target;
30                 this.translationCollector = c;
31         }
32         @Override
33         public boolean visit(MethodDeclaration methodDeclaration,
34                         org.eclipse.jdt.internal.compiler.lookup.ClassScope scope) {
35                 cm = methodDeclaration.binding;
36                 return true;
37         }
38         @Override
39         public void endVisit(MethodDeclaration methodDeclaration,
40                         org.eclipse.jdt.internal.compiler.lookup.ClassScope scope) {
41                 cm = null;
42         }
43         @Override
44         public boolean visit(ConstructorDeclaration constructorDeclaration,
45                         ClassScope scope) {
46                 cm = constructorDeclaration.binding;
47                 return super.visit(constructorDeclaration, scope);
48         }
49         @Override
50         public void endVisit(ConstructorDeclaration constructorDeclaration,
51                         ClassScope scope) {
52                 cm = null;
53         }
54         @Override
55         public boolean visit(AllocationExpression allocationExpression,
56                         BlockScope scope) {
57                 TaintSource test = new TaintSource(allocationExpression.binding);
58                 for (TaintSource taintSource : ts) {
59                         if (taintSource.equals(test)) {
60                                 check(null, scope,
61                                                 allocationExpression.arguments[taintSource.getTgt()],
62                                                 allocationExpression.toString());
63                                 return true;
64                         }
65                 }
66                 return super.visit(allocationExpression, scope);
67         }
68         @Override
69         public boolean visit(ExplicitConstructorCall explicitConstructor,
70                         BlockScope scope) {
71
72                 TaintSource t = new TaintSource(explicitConstructor.binding);
73
74                 for (TaintSource t0 : ts) {
75                         if (t0.equals(t)) {
76                                 Expression[] ags = explicitConstructor.arguments;
77                                 if (ags == null) {
78                                         System.out.println(explicitConstructor);
79                                         return true;
80                                 }
81                                 Expression e = ags[t0.getTgt()];
82                                 check(null, scope, e, explicitConstructor.toString());
83                                 break;
84                         }
85                 }
86                 return super.visit(explicitConstructor, scope);
87         }
88
89         @Override
90         public boolean visit(
91                         org.eclipse.jdt.internal.compiler.ast.MessageSend call,
92                         org.eclipse.jdt.internal.compiler.lookup.BlockScope scope) {
93                 if (call.binding == null) {
94                         System.out.println("Unbound:" + call + " in " + call.sourceStart());
95                         return true;
96                 }
97                 //System.out.println("Message");
98                 TaintSource t = new TaintSource(call.binding);
99
100                 for (TaintSource t0 : ts) {
101                         if (t0.equals(t)) {
102                                 Expression[] ags = call.arguments;
103                                 if (ags == null) {
104                                         System.out.println(call);
105                                         return true;
106                                 }
107                                 Expression e = ags[t0.getTgt()];
108                                 check(call, scope, e, call.toString());
109                                 break;
110                         }
111                 }
112                 return true;
113         }
114         private void check(org.eclipse.jdt.internal.compiler.ast.MessageSend call,
115                         org.eclipse.jdt.internal.compiler.lookup.BlockScope scope,
116                         Expression e, String caller) {
117                 if (e instanceof StringLiteral) {
118                         int[] lineEnds = null;
119                         int lineNumber = Util.getLineNumber(
120                                         e.sourceStart,
121                                         lineEnds = unit.compilationResult
122                                                         .getLineSeparatorPositions(), 0,
123                                         lineEnds.length - 1);
124
125                         String content = new String(((StringLiteral) e).source());
126                         translationCollector.add(
127                                         content,
128                                         new String(unit.compilationResult.fileName)
129                                                         .substring(translationCollector.base
130                                                                         .getAbsolutePath().length() + 1)
131                                                         + ":" + lineNumber);
132                         return;
133                 }
134
135                 if (e instanceof NullLiteral) {
136                         return;
137                 }
138
139                 if (e instanceof MessageSend) {
140                         MessageSend m2 = (MessageSend) e;
141                         TaintSource ts = new TaintSource(m2.binding);
142                         if (ts.equals(new TaintSource("org.cacert.gigi.pages", "Page",
143                                         "getTitle()", 0))) {
144                                 return;
145                         }
146                         if (m2.receiver.resolvedType.isCompatibleWith(scope
147                                         .getJavaLangEnum())) {
148                                 testEnum(m2.receiver, m2.binding);
149                                 System.out.println("ENUM-SRC: !" + m2.receiver);
150                         }
151                 }
152                 if (e.resolvedType.isCompatibleWith(scope.getJavaLangEnum())) {
153                         // TODO ?
154                         System.out.println("ENUM-Not-Hanled");
155                 }
156
157                 TaintSource b = cm == null ? null : new TaintSource(cm);
158                 for (TaintSource taintSource : ts) {
159                         if (taintSource.equals(b)
160                                         || (taintSource.getMaskOnly() != null && taintSource
161                                                         .getMaskOnly().equals(b))) {
162                                 return;
163                         }
164                 }
165                 if (e instanceof ConditionalExpression) {
166                         check(call, scope, ((ConditionalExpression) e).valueIfFalse, caller);
167                         check(call, scope, ((ConditionalExpression) e).valueIfTrue, caller);
168                         return;
169                 }
170
171                 System.out.println();
172
173                 System.out.println(new String(scope.enclosingClassScope()
174                                 .referenceType().compilationResult.fileName));
175                 System.out.println("Cannot Handle: " + e + " in "
176                                 + (call == null ? "constructor" : call.sourceStart) + " => "
177                                 + caller);
178                 System.out.println(e.getClass());
179                 System.out.println("To ignore: " + b.toConfLine());
180         }
181         private void testEnum(Expression e, MethodBinding binding) {
182                 if (binding.parameters.length != 0) {
183                         System.out.println("ERROR: meth");
184                         return;
185                 }
186                 System.out.println(e.resolvedType.getClass());
187                 String s2 = new String(e.resolvedType.qualifiedPackageName())
188                                 + "."
189                                 + (new String(e.resolvedType.qualifiedSourceName()).replace(
190                                                 '.', '$'));
191                 try {
192                         Class<?> c = Class.forName(s2);
193                         Enum<?>[] e1 = (Enum[]) c.getMethod("values").invoke(null);
194                         Method m = c.getMethod(new String(binding.selector));
195                         for (int j = 0; j < e1.length; j++) {
196                                 System.out.println(m.invoke(e1[j]));
197                         }
198                 } catch (ClassNotFoundException e1) {
199                         e1.printStackTrace();
200                 } catch (ReflectiveOperationException e1) {
201                         e1.printStackTrace();
202                 }
203                 System.out.println("ENUM-done: " + e + "!");
204                 return;
205         }
206 }