aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/apt
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2012-08-10 18:06:13 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2012-08-10 18:06:13 +0200
commit1be7da76012b246af24d0515d192bca85d65c823 (patch)
tree21d9675c00d812c6bbbf76edb80d38b16777740d /src/core/lombok/javac/apt
parent70317c73841d3e83b4b8008b68bea95753a5275f (diff)
downloadlombok-1be7da76012b246af24d0515d192bca85d65c823.tar.gz
lombok-1be7da76012b246af24d0515d192bca85d65c823.tar.bz2
lombok-1be7da76012b246af24d0515d192bca85d65c823.zip
* Added priorities to handlers, along with implementation of the priority system for javac and ecj.
* @Value now makes the class itself final by default.
Diffstat (limited to 'src/core/lombok/javac/apt')
-rw-r--r--src/core/lombok/javac/apt/Processor.java83
1 files changed, 59 insertions, 24 deletions
diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java
index d05a3bdf..190a369b 100644
--- a/src/core/lombok/javac/apt/Processor.java
+++ b/src/core/lombok/javac/apt/Processor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2010 The Project Lombok Authors.
+ * Copyright (C) 2009-2012 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,8 +30,10 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.IdentityHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.SortedSet;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
@@ -80,6 +82,14 @@ public class Processor extends AbstractProcessor {
placePostCompileAndDontMakeForceRoundDummiesHook();
transformer = new JavacTransformer(procEnv.getMessager());
trees = Trees.instance(procEnv);
+ SortedSet<Long> p = transformer.getPriorities();
+ if (p.isEmpty()) {
+ this.priorityLevels = new long[] {0L};
+ } else {
+ this.priorityLevels = new long[p.size()];
+ int i = 0;
+ for (Long prio : p) this.priorityLevels[i++] = prio;
+ }
}
private void placePostCompileAndDontMakeForceRoundDummiesHook() {
@@ -204,47 +214,72 @@ public class Processor extends AbstractProcessor {
}
}
- private final IdentityHashMap<JCCompilationUnit, Void> rootsAtPhase0 = new IdentityHashMap<JCCompilationUnit, Void>();
- private final IdentityHashMap<JCCompilationUnit, Void> rootsAtPhase1 = new IdentityHashMap<JCCompilationUnit, Void>();
- private int dummyCount = 0;
+ private final IdentityHashMap<JCCompilationUnit, Long> roots = new IdentityHashMap<JCCompilationUnit, Long>();
+ private long[] priorityLevels;
/** {@inheritDoc} */
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) return false;
- if (!rootsAtPhase0.isEmpty()) {
- ArrayList<JCCompilationUnit> cus = new ArrayList<JCCompilationUnit>(rootsAtPhase0.keySet());
- transformer.transform(true, processingEnv.getContext(), cus);
- rootsAtPhase1.putAll(rootsAtPhase0);
- rootsAtPhase0.clear();
- }
+ // We have: A sorted set of all priority levels: 'priorityLevels'
+
+ // Step 1: Take all CUs which aren't already in the map. Give them the first priority level.
for (Element element : roundEnv.getRootElements()) {
JCCompilationUnit unit = toUnit(element);
- if (unit != null) {
- if (!rootsAtPhase1.containsKey(unit)) rootsAtPhase0.put(unit, null);
+ if (unit == null) continue;
+ if (roots.containsKey(unit)) continue;
+ roots.put(unit, priorityLevels[0]);
+ }
+
+ // Step 2: For all CUs (in the map, not the roundEnv!), run them across all handlers at their current prio level.
+
+ for (long prio : priorityLevels) {
+ List<JCCompilationUnit> cusForThisRound = new ArrayList<JCCompilationUnit>();
+ for (Map.Entry<JCCompilationUnit, Long> entry : roots.entrySet()) {
+ Long prioOfCu = entry.getValue();
+ if (prioOfCu == null || prioOfCu != prio) continue;
+ cusForThisRound.add(entry.getKey());
}
+ transformer.transform(prio, processingEnv.getContext(), cusForThisRound);
}
- if (!rootsAtPhase0.isEmpty()) {
- ArrayList<JCCompilationUnit> cus = new ArrayList<JCCompilationUnit>(rootsAtPhase0.keySet());
- transformer.transform(false, processingEnv.getContext(), cus);
- JavacFiler filer = (JavacFiler) processingEnv.getFiler();
- if (!filer.newFiles()) {
- try {
- JavaFileObject dummy = filer.createSourceFile("lombok.dummy.ForceNewRound" + (dummyCount++));
- Writer w = dummy.openWriter();
- w.close();
- } catch (Exception e) {
- processingEnv.getMessager().printMessage(Kind.WARNING,
- "Can't force a new processing round. Lombok features that require resolution won't work.");
+ // Step 3: Push up all CUs to the next level. Set level to null if there is no next level.
+
+ boolean nextRoundNeeded = false;
+ for (int i = priorityLevels.length - 1; i >= 0; i--) {
+ Long curLevel = priorityLevels[i];
+ Long nextLevel = (i == priorityLevels.length - 1) ? null : priorityLevels[i + 1];
+ for (Map.Entry<JCCompilationUnit, Long> entry : roots.entrySet()) {
+ if (curLevel.equals(entry.getValue())) {
+ entry.setValue(nextLevel);
+ if (nextLevel != null) nextRoundNeeded = true;
}
}
}
+ // Step 4: If ALL values are null, quit. Else, force new round.
+
+ if (nextRoundNeeded) forceNewRound((JavacFiler) processingEnv.getFiler());
+
return false;
}
+ private int dummyCount = 0;
+ private void forceNewRound(JavacFiler filer) {
+ if (!filer.newFiles()) {
+ try {
+ JavaFileObject dummy = filer.createSourceFile("lombok.dummy.ForceNewRound" + (dummyCount++));
+ Writer w = dummy.openWriter();
+ w.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ processingEnv.getMessager().printMessage(Kind.WARNING,
+ "Can't force a new processing round. Lombok won't work.");
+ }
+ }
+ }
+
private JCCompilationUnit toUnit(Element element) {
TreePath path = trees == null ? null : trees.getPath(element);
if (path == null) return null;