-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathMethodsFirstChecker.java
More file actions
119 lines (110 loc) · 4.13 KB
/
MethodsFirstChecker.java
File metadata and controls
119 lines (110 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package liquidjava.processor.refinement_checker;
import java.util.ArrayList;
import java.util.List;
import liquidjava.diagnostics.Diagnostics;
import liquidjava.diagnostics.errors.LJError;
import liquidjava.processor.context.Context;
import liquidjava.processor.refinement_checker.general_checkers.MethodsFunctionsChecker;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtConstructor;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;
/** First visit to Spoon AST to get the method's refinements */
public class MethodsFirstChecker extends TypeChecker {
MethodsFunctionsChecker mfc;
List<String> visitedClasses;
Diagnostics diagnostics = Diagnostics.getInstance();
public MethodsFirstChecker(Context context, Factory factory) {
super(context, factory);
mfc = new MethodsFunctionsChecker(this);
visitedClasses = new ArrayList<>();
}
@Override
public <T> void visitCtClass(CtClass<T> ctClass) {
context.reinitializeContext();
if (visitedClasses.contains(ctClass.getQualifiedName()))
return;
else
visitedClasses.add(ctClass.getQualifiedName());
// visitInterfaces
if (!ctClass.getSuperInterfaces().isEmpty())
for (CtTypeReference<?> t : ctClass.getSuperInterfaces()) {
if (t.isInterface()) {
CtType<?> ct = t.getDeclaration();
if (ct instanceof CtInterface)
visitCtInterface((CtInterface<?>) ct);
}
}
// visitSubclasses
CtTypeReference<?> sup = ctClass.getSuperclass();
if (sup != null && sup.isClass()) {
CtType<?> ct = sup.getDeclaration();
if (ct instanceof CtClass)
visitCtClass((CtClass<?>) ct);
}
// first try-catch: process class-level annotations)
// errors here should not prevent visiting methods, constructors or fields of the class
try {
getRefinementFromAnnotation(ctClass);
handleStateSetsFromAnnotation(ctClass);
} catch (LJError e) {
diagnostics.add(e);
}
// second try-catch: visit class children (methods, constructors, fields)
// errors from one child should not prevent visiting sibling elements
try {
super.visitCtClass(ctClass);
} catch (LJError e) {
diagnostics.add(e);
}
}
@Override
public <T> void visitCtInterface(CtInterface<T> intrface) {
if (visitedClasses.contains(intrface.getQualifiedName()))
return;
else
visitedClasses.add(intrface.getQualifiedName());
if (getExternalRefinement(intrface).isPresent())
return;
// first try-catch: process interface-level annotations
// errors here should not prevent visiting the interface's methods
try {
getRefinementFromAnnotation(intrface);
handleStateSetsFromAnnotation(intrface);
} catch (LJError e) {
diagnostics.add(e);
}
// second try-catch: visit interface children (methods)
// errors from one child should not prevent visiting sibling methods
try {
super.visitCtInterface(intrface);
} catch (LJError e) {
diagnostics.add(e);
}
}
@Override
public <T> void visitCtConstructor(CtConstructor<T> c) {
context.enterContext();
try {
getRefinementFromAnnotation(c);
mfc.getConstructorRefinements(c);
super.visitCtConstructor(c);
} catch (LJError e) {
diagnostics.add(e);
}
context.exitContext();
}
public <R> void visitCtMethod(CtMethod<R> method) {
context.enterContext();
try {
mfc.getMethodRefinements(method);
super.visitCtMethod(method);
} catch (LJError e) {
diagnostics.add(e);
}
context.exitContext();
}
}