diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2012-08-10 18:06:13 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2012-08-10 18:06:13 +0200 |
commit | 1be7da76012b246af24d0515d192bca85d65c823 (patch) | |
tree | 21d9675c00d812c6bbbf76edb80d38b16777740d /src/core/lombok/javac/apt | |
parent | 70317c73841d3e83b4b8008b68bea95753a5275f (diff) | |
download | lombok-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.java | 83 |
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; |