|
1 | 1 | package liquidjava.processor; |
2 | 2 |
|
3 | | -import java.util.ArrayList; |
4 | | -import java.util.List; |
5 | | - |
6 | 3 | import liquidjava.diagnostics.Diagnostics; |
7 | 4 | import liquidjava.diagnostics.errors.LJError; |
8 | 5 | import liquidjava.processor.ann_generation.FieldGhostsGeneration; |
|
17 | 14 | /** Finds circular dependencies between packages */ |
18 | 15 | public class RefinementProcessor extends AbstractProcessor<CtPackage> { |
19 | 16 |
|
20 | | - List<CtPackage> visitedPackages = new ArrayList<>(); |
21 | 17 | Factory factory; |
22 | 18 | Diagnostics diagnostics = Diagnostics.getInstance(); |
23 | 19 |
|
24 | 20 | public RefinementProcessor(Factory factory) { |
25 | 21 | this.factory = factory; |
26 | 22 | } |
27 | 23 |
|
| 24 | + @Override |
| 25 | + public boolean isToBeProcessed(CtPackage pkg) { |
| 26 | + // Only let Spoon invoke us for the root package; |
| 27 | + // we handle sub-packages ourselves to guarantee parent-before-child order. |
| 28 | + return pkg.isUnnamedPackage(); |
| 29 | + } |
| 30 | + |
28 | 31 | @Override |
29 | 32 | public void process(CtPackage pkg) { |
30 | | - if (!visitedPackages.contains(pkg)) { |
31 | | - visitedPackages.add(pkg); |
32 | | - Context c = Context.getInstance(); |
33 | | - c.reinitializeAllContext(); |
34 | | - |
35 | | - try { |
36 | | - // process types in this package only, not sub-packages |
37 | | - // first pass: gather refinements |
38 | | - pkg.getTypes().forEach(type -> { |
39 | | - type.accept(new FieldGhostsGeneration(c, factory)); // generate annotations for field ghosts |
40 | | - type.accept(new ExternalRefinementTypeChecker(c, factory)); // process external refinements |
41 | | - type.accept(new MethodsFirstChecker(c, factory)); // double passing idea (instead of headers) |
42 | | - }); |
43 | | - |
44 | | - // second pass: check refinements |
45 | | - pkg.getTypes().forEach(type -> { |
46 | | - type.accept(new RefinementTypeChecker(c, factory)); |
47 | | - }); |
48 | | - } catch (LJError e) { |
49 | | - diagnostics.add(e); |
| 33 | + Context c = Context.getInstance(); |
| 34 | + c.reinitializeAllContext(); |
| 35 | + processPackage(pkg, c); |
| 36 | + } |
| 37 | + |
| 38 | + private void processPackage(CtPackage pkg, Context c) { |
| 39 | + try { |
| 40 | + // first pass: gather refinements |
| 41 | + pkg.getTypes().forEach(type -> { |
| 42 | + type.accept(new FieldGhostsGeneration(c, factory)); |
| 43 | + type.accept(new ExternalRefinementTypeChecker(c, factory)); |
| 44 | + type.accept(new MethodsFirstChecker(c, factory)); |
| 45 | + }); |
| 46 | + |
| 47 | + // second pass: check refinements |
| 48 | + pkg.getTypes().forEach(type -> { |
| 49 | + type.accept(new RefinementTypeChecker(c, factory)); |
| 50 | + }); |
| 51 | + |
| 52 | + // recurse into sub-packages (inheriting context) |
| 53 | + for (CtPackage subPkg : pkg.getPackages()) { |
| 54 | + processPackage(subPkg, c); |
50 | 55 | } |
| 56 | + } catch (LJError e) { |
| 57 | + diagnostics.add(e); |
51 | 58 | } |
52 | 59 | } |
53 | 60 | } |
0 commit comments