From 05d4168e3a64eb510e2793c219fe20d2555f7a47 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sun, 24 Jul 2011 08:04:18 +0200 Subject: Fixes issue 176 more thoroughly; even if both javac6 and javac7 are on the classpath, the 'right' BaseFileObject wrapper is now used. --- .../javac/apt/InterceptingJavaFileManager.java | 7 +- src/core/lombok/javac/apt/LombokFileObjects.java | 96 +++++++++++++--------- 2 files changed, 62 insertions(+), 41 deletions(-) (limited to 'src/core/lombok/javac') diff --git a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java index 979c1279..0d3cf905 100644 --- a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java +++ b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java @@ -32,23 +32,24 @@ import javax.tools.JavaFileObject.Kind; import lombok.core.DiagnosticsReceiver; final class InterceptingJavaFileManager extends ForwardingJavaFileManager { - private final DiagnosticsReceiver diagnostics; + private final LombokFileObjects.Compiler compiler; InterceptingJavaFileManager(JavaFileManager original, DiagnosticsReceiver diagnostics) { super(original); + this.compiler = LombokFileObjects.getCompiler(original); this.diagnostics = diagnostics; } @Override public JavaFileObject getJavaFileForOutput(Location location, String className, final Kind kind, FileObject sibling) throws IOException { if (className.startsWith("lombok.dummy.ForceNewRound")) { final String name = className.replace(".", "/") + kind.extension; - return LombokFileObjects.createEmpty(name, kind); + return LombokFileObjects.createEmpty(compiler, name, kind); } JavaFileObject fileObject = fileManager.getJavaFileForOutput(location, className, kind, sibling); if (kind != Kind.CLASS) { return fileObject; } - return LombokFileObjects.createIntercepting(fileObject, className, diagnostics); + return LombokFileObjects.createIntercepting(compiler, fileObject, className, diagnostics); } } \ No newline at end of file diff --git a/src/core/lombok/javac/apt/LombokFileObjects.java b/src/core/lombok/javac/apt/LombokFileObjects.java index ef1a6b56..21bb6da0 100644 --- a/src/core/lombok/javac/apt/LombokFileObjects.java +++ b/src/core/lombok/javac/apt/LombokFileObjects.java @@ -23,7 +23,9 @@ package lombok.javac.apt; import java.lang.reflect.Method; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; @@ -32,63 +34,81 @@ import lombok.core.DiagnosticsReceiver; //Can't use SimpleJavaFileObject so we copy/paste most of its content here, because javac doesn't follow the interface, //and casts to its own BaseFileObject type. D'oh! final class LombokFileObjects { - - private enum Compiler { + enum Compiler { JAVAC6 { + private Method decoderMethod = null; + private final AtomicBoolean decoderIsSet = new AtomicBoolean(); + @Override public JavaFileObject wrap(LombokFileObject fileObject) { return new Javac6BaseFileObjectWrapper(fileObject); } - }, + + @Override public Method getDecoderMethod() { + synchronized (decoderIsSet) { + if (decoderIsSet.get()) return decoderMethod; + decoderMethod = getDecoderMethod("com.sun.tools.javac.util.BaseFileObject"); + decoderIsSet.set(true); + return decoderMethod; + } + } + }, JAVAC7 { + private Method decoderMethod = null; + private final AtomicBoolean decoderIsSet = new AtomicBoolean(); + @Override public JavaFileObject wrap(LombokFileObject fileObject) { return new Javac7BaseFileObjectWrapper(fileObject); } + + @Override public Method getDecoderMethod() { + synchronized (decoderIsSet) { + if (decoderIsSet.get()) return decoderMethod; + decoderMethod = getDecoderMethod("com.sun.tools.javac.util.BaseFileObject"); + decoderIsSet.set(true); + return decoderMethod; + } + } }; - abstract JavaFileObject wrap(LombokFileObject fileObject); - } - - private static final Compiler compiler; - private static final Method decoderMethod; - - static { - Compiler c = null; - Method m = null; - try { - // In javac6, the BaseFileObject is located in - // com.sun.tools.javac.util - Class clazz = Class.forName("com.sun.tools.javac.util.BaseFileObject"); - c = Compiler.JAVAC6; + static Method getDecoderMethod(String className) { + Method m = null; try { - // The getDecoder method is not always present in javac6 - m = clazz.getDeclaredMethod("getDecoder", boolean.class); - } catch (NoSuchMethodException e) {} - } catch (ClassNotFoundException cnfe) { - // In javac7, the BaseFileObject has been moved to the package - // com.sun.tools.javac.file - try { - Class clazz = Class.forName("com.sun.tools.javac.file.BaseFileObject"); - c = Compiler.JAVAC7; - try { - m = clazz.getDeclaredMethod("getDecoder", boolean.class); - } catch (NoSuchMethodException e) {} - } catch (ClassNotFoundException cnfe2) { + m = Class.forName(className).getDeclaredMethod("getDecoder", boolean.class); + m.setAccessible(true); + } catch (NoSuchMethodException e) { + // Intentional fallthrough - getDecoder(boolean) is not always present. + } catch (ClassNotFoundException e) { + // Intentional fallthrough - getDecoder(boolean) is not always present. } + return m; } - compiler = c; - if (m != null) { - m.setAccessible(true); - } - decoderMethod = m; + + abstract JavaFileObject wrap(LombokFileObject fileObject); + abstract Method getDecoderMethod(); } private LombokFileObjects() {} - static JavaFileObject createEmpty(String name, Kind kind) { + static Compiler getCompiler(JavaFileManager jfm) { + String jfmClassName = jfm != null ? jfm.getClass().getName() : "null"; + if (jfmClassName.equals("com.sun.tools.javac.util.DefaultFileManager")) return Compiler.JAVAC6; + if (jfmClassName.equals("com.sun.tools.javac.file.JavacFileManager")) return Compiler.JAVAC7; + try { + if (Class.forName("com.sun.tools.javac.file.BaseFileObject") == null) throw new NullPointerException(); + return Compiler.JAVAC7; + } catch (Exception e) {} + try { + if (Class.forName("com.sun.tools.javac.util.BaseFileObject") == null) throw new NullPointerException(); + return Compiler.JAVAC6; + } catch (Exception e) {} + return null; + } + + static JavaFileObject createEmpty(Compiler compiler, String name, Kind kind) { return compiler.wrap(new EmptyLombokFileObject(name, kind)); } - static JavaFileObject createIntercepting(JavaFileObject delegate, String fileName, DiagnosticsReceiver diagnostics) { - return compiler.wrap(new InterceptingJavaFileObject(delegate, fileName, diagnostics, decoderMethod)); + static JavaFileObject createIntercepting(Compiler compiler, JavaFileObject delegate, String fileName, DiagnosticsReceiver diagnostics) { + return compiler.wrap(new InterceptingJavaFileObject(delegate, fileName, diagnostics, compiler.getDecoderMethod())); } } -- cgit