01: package spoon.vsuite.common;
02:
03: import java.util.List;
04:
05: import spoon.processing.AbstractProcessor;
06: import spoon.processing.Property;
07: import spoon.processing.Severity;
08: import spoon.reflect.code.CtFieldAccess;
09: import spoon.reflect.code.CtInvocation;
10: import spoon.reflect.declaration.CtMethod;
11: import spoon.reflect.declaration.ModifierKind;
12: import spoon.reflect.visitor.Query;
13: import spoon.reflect.visitor.filter.TypeFilter;
14:
15: public class CouldBeStaticMethodProcessor extends
16: AbstractProcessor<CtMethod<?>> {
17:
18: @Property
19: Severity level = Severity.WARNING;
20:
21: public void process(CtMethod<?> method) {
22: if (method.hasModifier(ModifierKind.STATIC))
23: return;
24: if (method.getReference().getOverridingExecutable() != null)
25: return;
26: if (method.getBody() == null)
27: return;
28: // TODO: this way of doing is wrong because one could access a non static
29: // element in a static method when having an instance on the same class
30: // => we have to check the target here
31: boolean couldBeStatic = true;
32: List<CtFieldAccess<?>> l = Query.getElements(method.getBody(),
33: new TypeFilter<CtFieldAccess<?>>(CtFieldAccess.class));
34: for (CtFieldAccess<?> fa : l) {
35: if (fa.getVariable().getDeclaringType().isAssignableFrom(
36: method.getDeclaringType().getReference())) {
37: if (!fa.getVariable().isStatic())
38: couldBeStatic = false;
39: }
40: }
41: List<CtInvocation<?>> li = Query.getElements(method.getBody(),
42: new TypeFilter<CtInvocation<?>>(CtInvocation.class));
43: for (CtInvocation<?> inv : li) {
44: if (inv.getExecutable().getDeclaringType()
45: .isAssignableFrom(
46: method.getDeclaringType().getReference())) {
47: if (!inv.getExecutable().isStatic())
48: couldBeStatic = false;
49: }
50: }
51: if (couldBeStatic) {
52: getFactory().getEnvironment().report(
53: this ,
54: level,
55: method,
56: "Method '" + method.getSimpleName()
57: + "' could be made static");
58: }
59: }
60:
61: }
|