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