diff options
-rw-r--r-- | src/core/lombok/javac/apt/InterceptingJavaFileManager.java | 74 | ||||
-rw-r--r-- | src/core/lombok/javac/apt/InterceptingJavaFileObject.java | 40 |
2 files changed, 107 insertions, 7 deletions
diff --git a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java index 738804ea..ef741c48 100644 --- a/src/core/lombok/javac/apt/InterceptingJavaFileManager.java +++ b/src/core/lombok/javac/apt/InterceptingJavaFileManager.java @@ -26,16 +26,26 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; import java.net.URI; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; import java.util.Iterator; import java.util.Set; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.NestingKind; import javax.tools.FileObject; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; import javax.tools.JavaFileObject.Kind; +import com.sun.tools.javac.util.BaseFileObject; + import lombok.core.DiagnosticsReceiver; final class InterceptingJavaFileManager implements JavaFileManager { @@ -47,21 +57,73 @@ final class InterceptingJavaFileManager implements JavaFileManager { this.diagnostics = diagnostics; } - @Override public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException { + @Override public JavaFileObject getJavaFileForOutput(Location location, String className, final Kind kind, FileObject sibling) throws IOException { if (className.startsWith("lombok.dummy.ForceNewRound")) { - String name = className.replace(".", "/") + kind.extension; - return new SimpleJavaFileObject(URI.create(name), kind) { - @Override public OutputStream openOutputStream() throws IOException { - return new ByteArrayOutputStream(); + final String name = className.replace(".", "/") + kind.extension; + // 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! + return new BaseFileObject() { + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + String baseName = simpleName + kind.extension; + return kind.equals(getKind()) + && (baseName.equals(toUri().getPath()) + || toUri().getPath().endsWith("/" + baseName)); + } + + @Override public URI toUri() { + return URI.create(name); } @Override public InputStream openInputStream() throws IOException { return new ByteArrayInputStream(new byte[0]); } + @Override public OutputStream openOutputStream() throws IOException { + return new ByteArrayOutputStream(); + } + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return ""; } + + @Override public Writer openWriter() throws IOException { + return new OutputStreamWriter(openOutputStream()); + } + + @Override public long getLastModified() { + return 0L; + } + + @Override public boolean delete() { + return false; + } + + @Override public Kind getKind() { + return kind; + } + + @SuppressWarnings("all") + @Override public String getName() { + return toUri().getPath(); + } + + @Override public NestingKind getNestingKind() { + return null; + } + + @Override public Modifier getAccessLevel() { + return null; + } + + @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { + return new StringReader(""); + } + + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { + CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); + CodingErrorAction action = ignoreEncodingErrors ? CodingErrorAction.REPLACE : CodingErrorAction.REPORT; + return decoder.onMalformedInput(action).onUnmappableCharacter(action); + } }; } JavaFileObject fileObject = delegate.getJavaFileForOutput(location, className, kind, sibling); diff --git a/src/core/lombok/javac/apt/InterceptingJavaFileObject.java b/src/core/lombok/javac/apt/InterceptingJavaFileObject.java index f59315cc..cd8b1f18 100644 --- a/src/core/lombok/javac/apt/InterceptingJavaFileObject.java +++ b/src/core/lombok/javac/apt/InterceptingJavaFileObject.java @@ -26,16 +26,22 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URI; +import java.nio.charset.CharsetDecoder; import javax.lang.model.element.Modifier; import javax.lang.model.element.NestingKind; import javax.tools.JavaFileObject; +import com.sun.tools.javac.util.BaseFileObject; + +import lombok.Lombok; import lombok.core.DiagnosticsReceiver; import lombok.core.PostCompiler; -final class InterceptingJavaFileObject implements JavaFileObject { +final class InterceptingJavaFileObject extends BaseFileObject { private final JavaFileObject delegate; private final String fileName; private final DiagnosticsReceiver diagnostics; @@ -46,10 +52,12 @@ final class InterceptingJavaFileObject implements JavaFileObject { this.diagnostics = diagnostics; } + @Override public OutputStream openOutputStream() throws IOException { return PostCompiler.wrapOutputStream(delegate.openOutputStream(), fileName, diagnostics); } + @Override public Writer openWriter() throws IOException { throw new UnsupportedOperationException("Can't use a write for class files"); // return original.openWriter(); @@ -60,47 +68,77 @@ final class InterceptingJavaFileObject implements JavaFileObject { /////////////////////// NOTHING CHANGED BELOW ////////////////////////////////////// + @Override public boolean delete() { return delegate.delete(); } + @Override public Modifier getAccessLevel() { return delegate.getAccessLevel(); } + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return delegate.getCharContent(ignoreEncodingErrors); } + @Override public Kind getKind() { return delegate.getKind(); } + @Override public long getLastModified() { return delegate.getLastModified(); } + @Override + @SuppressWarnings("all") public String getName() { return delegate.getName(); } + @Override public NestingKind getNestingKind() { return delegate.getNestingKind(); } + @Override public boolean isNameCompatible(String simpleName, Kind kind) { return delegate.isNameCompatible(simpleName, kind); } + @Override public InputStream openInputStream() throws IOException { return delegate.openInputStream(); } + @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { return delegate.openReader(ignoreEncodingErrors); } + @Override public URI toUri() { return delegate.toUri(); } + + protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { + if (delegate instanceof BaseFileObject) { + try { + Method m = BaseFileObject.class.getDeclaredMethod("getDecoder", boolean.class); + m.setAccessible(true); + return (CharsetDecoder) m.invoke(delegate, ignoreEncodingErrors); + } catch (NoSuchMethodException e) { + Lombok.sneakyThrow(e); + } catch (IllegalAccessException e) { + Lombok.sneakyThrow(e); + } catch (InvocationTargetException e) { + Lombok.sneakyThrow(e); + } + } + + throw new UnsupportedOperationException(); + } } |