From fc6670e1c4c31fbeaf658369c2771a2a93a0a9ba Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 4 Oct 2010 20:20:39 +0200 Subject: The previous commit (fix for ZIP closed errors) actually breaks lombok on systems with a javac that _does not_ close the annotation processor's jar. Fixed that, too. --- src/core/lombok/javac/apt/Processor.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java index 1d3d0c34..037f5ba5 100644 --- a/src/core/lombok/javac/apt/Processor.java +++ b/src/core/lombok/javac/apt/Processor.java @@ -157,6 +157,8 @@ public class Processor extends AbstractProcessor { ClassLoader unwrapped = (ClassLoader) f.get(processingEnv); ClassLoader wrapped = new WrappingClassLoader(unwrapped); f.set(processingEnv, wrapped); + } catch (NoSuchFieldException e) { + // Some versions of javac have this (and call close on it), some don't. I guess this one doesn't have it. } catch (Throwable t) { throw Lombok.sneakyThrow(t); } -- cgit From 17bcfda43b9e939ac22d5247ef98905741650432 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Tue, 2 Nov 2010 20:39:58 +0100 Subject: Issue 154: Add null-check to @Cleanup --- .../lombok/eclipse/handlers/HandleCleanup.java | 28 +++++++++++++++++++++- src/core/lombok/javac/handlers/HandleCleanup.java | 16 +++++++++---- .../resource/after-delombok/CleanupName.java | 8 +++++-- .../resource/after-delombok/CleanupPlain.java | 8 +++++-- test/transform/resource/after-ecj/CleanupName.java | 10 ++++++-- .../transform/resource/after-ecj/CleanupPlain.java | 10 ++++++-- 6 files changed, 67 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/HandleCleanup.java b/src/core/lombok/eclipse/handlers/HandleCleanup.java index d296e96b..33ab7fb9 100644 --- a/src/core/lombok/eclipse/handlers/HandleCleanup.java +++ b/src/core/lombok/eclipse/handlers/HandleCleanup.java @@ -37,9 +37,13 @@ import org.eclipse.jdt.internal.compiler.ast.Assignment; import org.eclipse.jdt.internal.compiler.ast.Block; import org.eclipse.jdt.internal.compiler.ast.CaseStatement; import org.eclipse.jdt.internal.compiler.ast.CastExpression; +import org.eclipse.jdt.internal.compiler.ast.EqualExpression; +import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; +import org.eclipse.jdt.internal.compiler.ast.NullLiteral; +import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; @@ -157,7 +161,29 @@ public class HandleCleanup implements EclipseAnnotationHandler { } unsafeClose.nameSourcePosition = nameSourcePosition; unsafeClose.selector = cleanupName.toCharArray(); - finallyBlock[0] = unsafeClose; + + + int pS = ast.sourceStart, pE = ast.sourceEnd; + long p = (long)pS << 32 | pE; + + SingleNameReference varName = new SingleNameReference(decl.name, p); + Eclipse.setGeneratedBy(varName, ast); + NullLiteral nullLiteral = new NullLiteral(pS, pE); + Eclipse.setGeneratedBy(nullLiteral, ast); + EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, OperatorIds.NOT_EQUAL); + equalExpression.sourceStart = pS; equalExpression.sourceEnd = pE; + Eclipse.setGeneratedBy(equalExpression, ast); + + Block closeBlock = new Block(0); + closeBlock.statements = new Statement[1]; + closeBlock.statements[0] = unsafeClose; + Eclipse.setGeneratedBy(closeBlock, ast); + IfStatement ifStatement = new IfStatement(equalExpression, closeBlock, 0, 0); + Eclipse.setGeneratedBy(ifStatement, ast); + + + + finallyBlock[0] = ifStatement; tryStatement.finallyBlock = new Block(0); Eclipse.setGeneratedBy(tryStatement.finallyBlock, ast); tryStatement.finallyBlock.statements = finallyBlock; diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 2c89d9ad..779dd3ea 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -30,10 +30,12 @@ import lombok.javac.JavacNode; import org.mangosdk.spi.ProviderFor; +import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; +import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCCase; import com.sun.tools.javac.tree.JCTree.JCCatch; @@ -41,6 +43,7 @@ import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCIf; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCTypeCast; @@ -108,11 +111,16 @@ public class HandleCleanup implements JavacAnnotationHandler { doAssignmentCheck(annotationNode, tryBlock, decl.name); TreeMaker maker = annotationNode.getTreeMaker(); - JCFieldAccess cleanupCall = maker.Select(maker.Ident(decl.name), annotationNode.toName(cleanupName)); - List finalizerBlock = List.of(maker.Exec( - maker.Apply(List.nil(), cleanupCall, List.nil()))); + JCFieldAccess cleanupMethod = maker.Select(maker.Ident(decl.name), annotationNode.toName(cleanupName)); + List cleanupCall = List.of(maker.Exec( + maker.Apply(List.nil(), cleanupMethod, List.nil()))); + + JCBinary isNull = maker.Binary(JCTree.NE, maker.Ident(decl.name), maker.Literal(TypeTags.BOT, null)); + + JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null); + + JCBlock finalizer = maker.Block(0, List.of(ifNotNullCleanup)); - JCBlock finalizer = maker.Block(0, finalizerBlock); newStatements = newStatements.append(maker.Try(maker.Block(0, tryBlock), List.nil(), finalizer)); if (blockNode instanceof JCBlock) { diff --git a/test/transform/resource/after-delombok/CleanupName.java b/test/transform/resource/after-delombok/CleanupName.java index cd29eb68..0201008e 100644 --- a/test/transform/resource/after-delombok/CleanupName.java +++ b/test/transform/resource/after-delombok/CleanupName.java @@ -4,7 +4,9 @@ class CleanupName { try { System.out.println(o); } finally { - o.toString(); + if (o != null) { + o.toString(); + } } } void test2() { @@ -12,7 +14,9 @@ class CleanupName { try { System.out.println(o); } finally { - o.toString(); + if (o != null) { + o.toString(); + } } } } diff --git a/test/transform/resource/after-delombok/CleanupPlain.java b/test/transform/resource/after-delombok/CleanupPlain.java index 35d51543..1a19442f 100644 --- a/test/transform/resource/after-delombok/CleanupPlain.java +++ b/test/transform/resource/after-delombok/CleanupPlain.java @@ -9,10 +9,14 @@ class CleanupPlain { out.flush(); } } finally { - out.close(); + if (out != null) { + out.close(); + } } } finally { - in.close(); + if (in != null) { + in.close(); + } } } } diff --git a/test/transform/resource/after-ecj/CleanupName.java b/test/transform/resource/after-ecj/CleanupName.java index 944a81e1..4011721b 100644 --- a/test/transform/resource/after-ecj/CleanupName.java +++ b/test/transform/resource/after-ecj/CleanupName.java @@ -10,7 +10,10 @@ class CleanupName { } finally { - o.toString(); + if ((o != null)) + { + o.toString(); + } } } void test2() { @@ -21,7 +24,10 @@ class CleanupName { } finally { - o.toString(); + if ((o != null)) + { + o.toString(); + } } } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/CleanupPlain.java b/test/transform/resource/after-ecj/CleanupPlain.java index 6754b4f6..fe8d7571 100644 --- a/test/transform/resource/after-ecj/CleanupPlain.java +++ b/test/transform/resource/after-ecj/CleanupPlain.java @@ -18,12 +18,18 @@ class CleanupPlain { } finally { - out.close(); + if ((out != null)) + { + out.close(); + } } } finally { - in.close(); + if ((in != null)) + { + in.close(); + } } } } \ No newline at end of file -- cgit From 6e2924bcf2ceb390c0f8c712e8ee9c4428173ded Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 3 Nov 2010 00:40:14 +0100 Subject: Some small framework updates to accomodate resolution. --- src/core/lombok/core/LombokNode.java | 4 ++++ src/core/lombok/javac/HandlerLibrary.java | 8 +++++++- src/core/lombok/javac/JavacASTAdapter.java | 5 +++++ src/core/lombok/javac/JavacASTVisitor.java | 10 ++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index 6d0f3147..4a57e080 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.java @@ -78,6 +78,10 @@ public abstract class LombokNode, L extends LombokNode Date: Wed, 3 Nov 2010 00:42:32 +0100 Subject: big changes to delombok to prep for resolution, when sourcepath and classpath are relevant, and the flow needs to be parse all, then enter all, then transform all, instead of parse->enter->transform sequentially for each file in isolation. --- .../lombok/delombok/CommentCollectingScanner.java | 2 +- .../lombok/delombok/CommentPreservingParser.java | 170 ------------------ src/delombok/lombok/delombok/Delombok.java | 190 +++++++++++++++++---- src/delombok/lombok/delombok/DelombokResult.java | 62 +++++++ .../lombok/delombok/PrettyCommentsPrinter.java | 16 +- src/delombok/lombok/delombok/ant/DelombokTask.java | 51 +++++- test/core/src/lombok/AbstractRunTests.java | 9 +- test/core/src/lombok/RunTestsViaDelombok.java | 5 +- test/pretty/resource/before/Annotation.java | 1 + 9 files changed, 287 insertions(+), 219 deletions(-) delete mode 100644 src/delombok/lombok/delombok/CommentPreservingParser.java create mode 100644 src/delombok/lombok/delombok/DelombokResult.java (limited to 'src') diff --git a/src/delombok/lombok/delombok/CommentCollectingScanner.java b/src/delombok/lombok/delombok/CommentCollectingScanner.java index 2552cbf7..c930bc62 100644 --- a/src/delombok/lombok/delombok/CommentCollectingScanner.java +++ b/src/delombok/lombok/delombok/CommentCollectingScanner.java @@ -25,7 +25,7 @@ import java.nio.CharBuffer; import lombok.delombok.Comment.EndConnection; import lombok.delombok.Comment.StartConnection; -import lombok.delombok.CommentPreservingParser.Comments; +import lombok.delombok.Delombok.Comments; import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.util.Context; diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java deleted file mode 100644 index 87c02dcd..00000000 --- a/src/delombok/lombok/delombok/CommentPreservingParser.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.delombok; - -import java.io.IOException; -import java.io.Writer; -import java.util.Collections; -import java.util.Date; - -import javax.annotation.processing.Messager; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.Element; -import javax.tools.DiagnosticListener; -import javax.tools.JavaFileObject; -import javax.tools.Diagnostic.Kind; - -import lombok.javac.DeleteLombokAnnotations; -import lombok.javac.JavacTransformer; - -import com.sun.tools.javac.main.JavaCompiler; -import com.sun.tools.javac.main.OptionName; -import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; -import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.Options; - -public class CommentPreservingParser { - private final String encoding; - private boolean deleteLombokAnnotations = false; - private DiagnosticListener diagnostics = null; - - public CommentPreservingParser() { - this("utf-8"); - } - - public CommentPreservingParser(String encoding) { - this.encoding = encoding; - } - - public void setDeleteLombokAnnotations(boolean deleteLombokAnnotations) { - this.deleteLombokAnnotations = deleteLombokAnnotations; - } - - public void setDiagnosticsListener(DiagnosticListener diagnostics) { - this.diagnostics = diagnostics; - } - - public ParseResult parse(JavaFileObject source, boolean forceProcessing) throws IOException { - return doParse(source, forceProcessing); - } - - public ParseResult parse(String fileName, boolean forceProcessing) throws IOException { - return doParse(fileName, forceProcessing); - } - - private ParseResult doParse(Object source, boolean forceProcessing) throws IOException { - Context context = new Context(); - - Options.instance(context).put(OptionName.ENCODING, encoding); - - if (diagnostics != null) context.put(DiagnosticListener.class, diagnostics); - - CommentCollectingScanner.Factory.preRegister(context); - - JavaCompiler compiler = new JavaCompiler(context) { - @Override - protected boolean keepComments() { - return true; - } - }; - - compiler.genEndPos = true; - - Comments comments = new Comments(); - context.put(Comments.class, comments); - if (deleteLombokAnnotations) context.put(DeleteLombokAnnotations.class, new DeleteLombokAnnotations(true)); - - comments.comments = List.nil(); - - JCCompilationUnit cu; - if (source instanceof JavaFileObject) { - cu = compiler.parse((JavaFileObject) source); - } else { - @SuppressWarnings("deprecation") - JCCompilationUnit unit = compiler.parse((String)source); - cu = unit; - } - - boolean changed = new JavacTransformer(messager).transform(context, Collections.singleton(cu)); - return new ParseResult(comments.comments, cu, forceProcessing || changed); - } - - private static final Messager messager = new Messager() { - @Override public void printMessage(Kind kind, CharSequence msg) { - System.out.printf("%s: %s\n", kind, msg); - } - - @Override public void printMessage(Kind kind, CharSequence msg, Element e) { - System.out.printf("%s: %s\n", kind, msg); - } - - @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a) { - System.out.printf("%s: %s\n", kind, msg); - } - - @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) { - System.out.printf("%s: %s\n", kind, msg); - } - }; - - static class Comments { - List comments = List.nil(); - - void add(Comment comment) { - comments = comments.append(comment); - } - } - - public static class ParseResult { - private final List comments; - private final JCCompilationUnit compilationUnit; - private final boolean changed; - - private ParseResult(List comments, JCCompilationUnit compilationUnit, boolean changed) { - this.comments = comments; - this.compilationUnit = compilationUnit; - this.changed = changed; - } - - public void print(Writer out) throws IOException { - if (!changed) { - JavaFileObject sourceFile = compilationUnit.getSourceFile(); - if (sourceFile != null) { - out.write(sourceFile.getCharContent(true).toString()); - return; - } - } - - out.write("// Generated by delombok at "); - out.write(String.valueOf(new Date())); - out.write(System.getProperty("line.separator")); - - compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments)); - } - - public boolean isChanged() { - return changed; - } - } -} diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 56994f78..6866d97f 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -30,16 +30,33 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.Writer; +import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import javax.annotation.processing.Messager; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; +import javax.tools.Diagnostic.Kind; -import lombok.delombok.CommentPreservingParser.ParseResult; +import lombok.javac.DeleteLombokAnnotations; +import lombok.javac.JavacTransformer; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; import com.zwitserloot.cmdreader.CmdReader; import com.zwitserloot.cmdreader.Description; import com.zwitserloot.cmdreader.Excludes; @@ -50,16 +67,24 @@ import com.zwitserloot.cmdreader.Shorthand; public class Delombok { private Charset charset = Charset.defaultCharset(); - private CommentPreservingParser parser = new CommentPreservingParser(); + private Context context = new Context(); + private Writer presetWriter; - { - parser.setDeleteLombokAnnotations(true); + public void setWriter(Writer writer) { + this.presetWriter = writer; + } + + public Delombok() { + context.put(DeleteLombokAnnotations.class, new DeleteLombokAnnotations(true)); } private PrintStream feedback = System.err; private boolean verbose; private boolean noCopy; private boolean force = false; + private String classpath, sourcepath; + private LinkedHashMap fileToBase = new LinkedHashMap(); + private List filesToParse = new ArrayList(); /** If null, output to standard out. */ private File output = null; @@ -88,6 +113,14 @@ public class Delombok { @Mandatory(onlyIfNot={"print", "help"}) private String target; + @Shorthand("c") + @Description("Classpath (analogous to javac -cp option)") + private String classpath; + + @Shorthand("s") + @Description("Sourcepath (analogous to javac -sourcepath option)") + private String sourcepath; + @Description("Files to delombok. Provide either a file, or a directory. If you use a directory, all files in it (recursive) are delombok-ed") @Sequential private List input = new ArrayList(); @@ -138,21 +171,29 @@ public class Delombok { if (args.verbose) delombok.setVerbose(true); if (args.nocopy) delombok.setNoCopy(true); - if (args.print) delombok.setOutputToStandardOut(); - else delombok.setOutput(new File(args.target)); + if (args.print) { + delombok.setOutputToStandardOut(); + } else { + delombok.setOutput(new File(args.target)); + } + + if (args.classpath != null) delombok.setClasspath(args.classpath); + if (args.sourcepath != null) delombok.setSourcepath(args.sourcepath); for (String in : args.input) { try { File f = new File(in); if (f.isFile()) { - delombok.delombok(f.getParentFile(), f.getName()); + delombok.addFile(f.getParentFile(), f.getName()); } else if (f.isDirectory()) { - delombok.delombok(f); + delombok.addDirectory(f); } else if (!f.exists()) { if (!args.quiet) System.err.println("WARNING: does not exist - skipping: " + f); } else { if (!args.quiet) System.err.println("WARNING: not a standard file or directory - skipping: " + f); } + + delombok.delombok(); } catch (Exception e) { if (!args.quiet) { String msg = e.getMessage(); @@ -168,12 +209,12 @@ public class Delombok { } public void setCharset(String charsetName) throws UnsupportedCharsetException { + charset = Charset.forName(charsetName); } - public void setDiagnosticsListener(DiagnosticListener diagnostics) { - parser.setDiagnosticsListener(diagnostics); + if (diagnostics != null) context.put(DiagnosticListener.class, diagnostics); } public void setForceProcess(boolean force) { @@ -184,6 +225,14 @@ public class Delombok { this.feedback = feedback; } + public void setClasspath(String classpath) { + this.classpath = classpath; + } + + public void setSourcepath(String sourcepath) { + this.sourcepath = sourcepath; + } + public void setVerbose(boolean verbose) { this.verbose = verbose; } @@ -204,15 +253,15 @@ public class Delombok { this.output = null; } - public void delombok(File base) throws IOException { - delombok0(false, base, "", 0); + public void addDirectory(File base) throws IOException { + addDirectory0(false, base, "", 0); } - public void process(boolean copy, File base, String name) throws IOException { + public void addDirectory1(boolean copy, File base, String name) throws IOException { File f = new File(base, name); if (f.isFile()) { String extension = getExtension(f); - if (extension.equals("java")) delombok(base, name); + if (extension.equals("java")) addFile(base, name); else if (extension.equals("class")) skipClass(name); else copy(copy, base, name); } else if (!f.exists()) { @@ -222,7 +271,7 @@ public class Delombok { } } - private void delombok0(boolean inHiddenDir, File base, String suffix, int loop) throws IOException { + private void addDirectory0(boolean inHiddenDir, File base, String suffix, int loop) throws IOException { File dir = suffix.isEmpty() ? base : new File(base, suffix); if (dir.isDirectory()) { @@ -236,7 +285,7 @@ public class Delombok { feedback.printf("Only processing java files (not copying non-java files) in %s because it's a hidden directory.\n", canonical(dir)); } for (File f : list) { - delombok0(inHiddenDir || thisDirIsHidden, base, suffix + (suffix.isEmpty() ? "" : File.separator) + f.getName(), loop + 1); + addDirectory0(inHiddenDir || thisDirIsHidden, base, suffix + (suffix.isEmpty() ? "" : File.separator) + f.getName(), loop + 1); } } else { if (!thisDirIsHidden && !noCopy && !inHiddenDir && output != null && !suffix.isEmpty()) { @@ -247,7 +296,7 @@ public class Delombok { } } } else { - process(!inHiddenDir && !noCopy, base, suffix); + addDirectory1(!inHiddenDir && !noCopy, base, suffix); } } @@ -288,34 +337,96 @@ public class Delombok { } } - public void delombok(JavaFileObject file, Writer writer) throws IOException { - ParseResult result = parser.parse(file, force); - result.print(writer); + public void addFile(File base, String fileName) throws IOException { + if (output != null && canonical(base).equals(canonical(output))) throw new IOException( + "DELOMBOK: Output file and input file refer to the same filesystem location. Specify a separate path for output."); + + File f = new File(base, fileName); + filesToParse.add(f); + fileToBase.put(f, base); } - public void delombok(String file, Writer writer) throws IOException { - ParseResult result = parser.parse(file, force); - result.print(writer); + private static com.sun.tools.javac.util.List toJavacList(List list) { + com.sun.tools.javac.util.List out = com.sun.tools.javac.util.List.nil(); + ListIterator li = list.listIterator(list.size()); + while (li.hasPrevious()) out = out.prepend(li.previous()); + return out; } - public void delombok(File base, String fileName) throws IOException { - if (output != null && canonical(base).equals(canonical(output))) throw new IOException( - "DELOMBOK: Output file and input file refer to the same filesystem location. Specify a separate path for output."); + public boolean delombok() throws IOException { + Options options = Options.instance(context); + options.put(OptionName.ENCODING, charset.name()); + if (classpath != null) options.put(OptionName.CLASSPATH, classpath); + if (sourcepath != null) options.put(OptionName.SOURCEPATH, sourcepath); + CommentCollectingScanner.Factory.preRegister(context); - ParseResult result = parser.parse(new File(base, fileName).getAbsolutePath(), force); + JavaCompiler compiler = new JavaCompiler(context); + compiler.keepComments = true; + compiler.genEndPos = true; - if (verbose) feedback.printf("File: %s [%s]\n", fileName, result.isChanged() ? "delombok-ed" : "unchanged"); + List roots = new ArrayList(); + Map commentsMap = new IdentityHashMap(); + Map baseMap = new IdentityHashMap(); + for (File fileToParse : filesToParse) { + Comments comments = new Comments(); + context.put(Comments.class, comments); + + @SuppressWarnings("deprecation") + JCCompilationUnit unit = compiler.parse(fileToParse.getAbsolutePath()); + + commentsMap.put(unit, comments); + baseMap.put(unit, fileToBase.get(fileToParse)); + roots.add(unit); + } - Writer rawWriter = output == null ? createStandardOutWriter() : createFileWriter(output, fileName); - BufferedWriter writer = new BufferedWriter(rawWriter); + if (compiler.errorCount() > 0) return false; + compiler.enterTrees(toJavacList(roots)); - try { - result.print(writer); - } finally { - writer.close(); + for (JCCompilationUnit unit : roots) { + boolean changed = new JavacTransformer(messager).transform(context, Collections.singleton(unit)); + DelombokResult result = new DelombokResult(commentsMap.get(unit).comments, unit, force || changed); + if (verbose) feedback.printf("File: %s [%s]\n", unit.sourcefile.getName(), result.isChanged() ? "delomboked" : "unchanged"); + Writer rawWriter; + if (presetWriter != null) rawWriter = presetWriter; + else if (output == null) rawWriter = createStandardOutWriter(); + else rawWriter = createFileWriter(output, baseMap.get(unit), unit.sourcefile.toUri()); + BufferedWriter writer = new BufferedWriter(rawWriter); + try { + result.print(writer); + } finally { + writer.close(); + } + } + + return true; + } + + public static class Comments { + public com.sun.tools.javac.util.List comments = com.sun.tools.javac.util.List.nil(); + + void add(Comment comment) { + comments = comments.append(comment); } } + private static final Messager messager = new Messager() { + @Override public void printMessage(Kind kind, CharSequence msg) { + System.out.printf("%s: %s\n", kind, msg); + } + + @Override public void printMessage(Kind kind, CharSequence msg, Element e) { + System.out.printf("%s: %s\n", kind, msg); + } + + @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a) { + System.out.printf("%s: %s\n", kind, msg); + } + + @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) { + System.out.printf("%s: %s\n", kind, msg); + } + }; + private static String canonical(File dir) { try { return dir.getCanonicalPath(); @@ -330,8 +441,15 @@ public class Delombok { return idx == -1 ? "" : name.substring(idx+1); } - private Writer createFileWriter(File base, String fileName) throws IOException { - File outFile = new File(base, fileName); + private Writer createFileWriter(File outBase, File inBase, URI file) throws IOException { + URI relative = inBase.toURI().relativize(file); + File outFile; + if (relative.isAbsolute()) { + outFile = new File(outBase, new File(relative).getName()); + } else { + outFile = new File(outBase, relative.getPath()); + } + outFile.getParentFile().mkdirs(); FileOutputStream out = new FileOutputStream(outFile); return createUnicodeEscapeWriter(out); diff --git a/src/delombok/lombok/delombok/DelombokResult.java b/src/delombok/lombok/delombok/DelombokResult.java new file mode 100644 index 00000000..717a3bf1 --- /dev/null +++ b/src/delombok/lombok/delombok/DelombokResult.java @@ -0,0 +1,62 @@ +/* + * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */package lombok.delombok; + +import java.io.IOException; +import java.io.Writer; +import java.util.Date; + +import javax.tools.JavaFileObject; + +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.List; + +public class DelombokResult { + private final List comments; + private final JCCompilationUnit compilationUnit; + private final boolean changed; + + public DelombokResult(List comments, JCCompilationUnit compilationUnit, boolean changed) { + this.comments = comments; + this.compilationUnit = compilationUnit; + this.changed = changed; + } + + public void print(Writer out) throws IOException { + if (!changed) { + JavaFileObject sourceFile = compilationUnit.getSourceFile(); + if (sourceFile != null) { + out.write(sourceFile.getCharContent(true).toString()); + return; + } + } + + out.write("// Generated by delombok at "); + out.write(String.valueOf(new Date())); + out.write(System.getProperty("line.separator")); + + compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments)); + } + + public boolean isChanged() { + return changed; + } +} \ No newline at end of file diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 55c0e1bc..16c06f50 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -670,9 +670,11 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void visitMethodDef(JCMethodDecl tree) { try { + boolean isConstructor = tree.name == tree.name.table.fromChars("".toCharArray(), 0, 6); // when producing source output, omit anonymous constructors - if (tree.name == tree.name.table.fromChars("".toCharArray(), 0, 6) && - enclClassName == null) return; + if (isConstructor && enclClassName == null) return; + boolean isGeneratedConstructor = isConstructor && ((tree.mods.flags & Flags.GENERATEDCONSTR) != 0); + if (isGeneratedConstructor) return; println(); align(); printDocComment(tree); printExpr(tree.mods); @@ -1442,9 +1444,13 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { print("@"); printExpr(tree.annotationType); if (tree.args.nonEmpty()) { - print("("); - printExprs(tree.args); - print(")"); + print("("); + if (tree.args.length() == 1 && tree.args.get(0) instanceof JCAssign) { + JCExpression lhs = ((JCAssign)tree.args.get(0)).lhs; + if (lhs instanceof JCIdent && ((JCIdent)lhs).name.toString().equals("value")) tree.args = List.of(((JCAssign)tree.args.get(0)).rhs); + } + printExprs(tree.args); + print(")"); } } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/src/delombok/lombok/delombok/ant/DelombokTask.java b/src/delombok/lombok/delombok/ant/DelombokTask.java index 4a40b874..40c3c63e 100644 --- a/src/delombok/lombok/delombok/ant/DelombokTask.java +++ b/src/delombok/lombok/delombok/ant/DelombokTask.java @@ -32,14 +32,55 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.resources.FileResource; public class DelombokTask extends Task { private File fromDir, toDir; + private Path classpath; + private Path sourcepath; private boolean verbose; private String encoding; private Path path; + public void setClasspath(Path classpath) { + if (this.classpath == null) { + this.classpath = classpath; + } else { + this.classpath.append(classpath); + } + } + + public Path createClasspath() { + if (classpath == null) { + classpath = new Path(getProject()); + } + return classpath.createPath(); + } + + public void setClasspathRef(Reference r) { + createClasspath().setRefid(r); + } + + public void setSourcepath(Path sourcepath) { + if (this.sourcepath == null) { + this.sourcepath = sourcepath; + } else { + this.sourcepath.append(sourcepath); + } + } + + public Path createSourcepath() { + if (sourcepath == null) { + sourcepath = new Path(getProject()); + } + return sourcepath.createPath(); + } + + public void setSourcepathRef(Reference r) { + createSourcepath().setRefid(r); + } + public void setFrom(File dir) { this.fromDir = dir; } @@ -75,9 +116,12 @@ public class DelombokTask extends Task { throw new BuildException("Unknown charset: " + encoding, getLocation()); } + if (classpath != null) delombok.setClasspath(classpath.toString()); + if (sourcepath != null) delombok.setSourcepath(sourcepath.toString()); + delombok.setOutput(toDir); try { - if (fromDir != null) delombok.delombok(fromDir); + if (fromDir != null) delombok.addDirectory(fromDir); else { Iterator it = path.iterator(); while (it.hasNext()) { @@ -85,12 +129,13 @@ public class DelombokTask extends Task { File baseDir = fileResource.getBaseDir(); if (baseDir == null) { File file = fileResource.getFile(); - delombok.process(false, file.getParentFile(), file.getName()); + delombok.addFile(file.getParentFile(), file.getName()); } else { - delombok.process(false, baseDir, fileResource.getName()); + delombok.addFile(baseDir, fileResource.getName()); } } } + delombok.delombok(); } catch (IOException e) { throw new BuildException("I/O problem during delombok", e, getLocation()); } diff --git a/test/core/src/lombok/AbstractRunTests.java b/test/core/src/lombok/AbstractRunTests.java index 4241646b..7d5992be 100644 --- a/test/core/src/lombok/AbstractRunTests.java +++ b/test/core/src/lombok/AbstractRunTests.java @@ -37,12 +37,12 @@ public abstract class AbstractRunTests { public void compareFile(DirectoryRunner.TestParams params, File file) throws Throwable { StringBuilder messages = new StringBuilder(); - StringWriter result = new StringWriter(); - transformCode(messages, result, file); + StringWriter writer = new StringWriter(); + transformCode(messages, writer, file); compare( file.getName(), readFile(params.getAfterDirectory(), file, false), - result.toString(), + writer.toString(), readFile(params.getMessagesDirectory(), file, true), messages.toString(), params.printErrors()); @@ -111,6 +111,9 @@ public abstract class AbstractRunTests { private static void compareContent(String name, String expectedFile, String actualFile) { String[] expectedLines = expectedFile.split("(\\r?\\n)"); String[] actualLines = actualFile.split("(\\r?\\n)"); + if (expectedLines[0].startsWith("// Generated by delombok at ")) { + expectedLines[0] = ""; + } if (actualLines[0].startsWith("// Generated by delombok at ")) { actualLines[0] = ""; } diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java index 50fad33e..59a0ee89 100644 --- a/test/core/src/lombok/RunTestsViaDelombok.java +++ b/test/core/src/lombok/RunTestsViaDelombok.java @@ -51,6 +51,9 @@ public class RunTestsViaDelombok extends AbstractRunTests { } }); - delombok.delombok(file.getAbsolutePath(), result); + delombok.addFile(file.getParentFile(), file.getName()); + delombok.setSourcepath(file.getParentFile().getAbsolutePath()); + delombok.setWriter(result); + delombok.delombok(); } } diff --git a/test/pretty/resource/before/Annotation.java b/test/pretty/resource/before/Annotation.java index edd1a5e7..24868acd 100644 --- a/test/pretty/resource/before/Annotation.java +++ b/test/pretty/resource/before/Annotation.java @@ -1,3 +1,4 @@ +//ignore @SuppressWarnings("all") class Annotation { @Override -- cgit From f1cf083890c223bf7245190264438740ee724bc9 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 3 Nov 2010 00:42:58 +0100 Subject: val in java, including tests and javac resolution utilities. --- src/core/lombok/javac/JavacResolution.java | 480 +++++++++++++++++++++ src/core/lombok/javac/TreeMirrorMaker.java | 50 +++ src/core/lombok/javac/handlers/HandleVal.java | 104 +++++ .../resource/after-delombok/ValComplex.java | 20 + .../resource/after-delombok/ValErrors.java | 8 + .../resource/after-delombok/ValInFor.java | 20 + .../resource/after-delombok/ValLessSimple.java | 26 ++ .../resource/after-delombok/ValSimple.java | 24 ++ .../resource/after-delombok/ValWeirdTypes.java | 47 ++ test/transform/resource/before/ValComplex.java | 20 + test/transform/resource/before/ValErrors.java | 9 + test/transform/resource/before/ValInFor.java | 20 + test/transform/resource/before/ValLessSimple.java | 31 ++ test/transform/resource/before/ValSimple.java | 26 ++ test/transform/resource/before/ValWeirdTypes.java | 54 +++ .../messages-delombok/ValErrors.java.messages | 2 + 16 files changed, 941 insertions(+) create mode 100644 src/core/lombok/javac/JavacResolution.java create mode 100644 src/core/lombok/javac/TreeMirrorMaker.java create mode 100644 src/core/lombok/javac/handlers/HandleVal.java create mode 100644 test/transform/resource/after-delombok/ValComplex.java create mode 100644 test/transform/resource/after-delombok/ValErrors.java create mode 100644 test/transform/resource/after-delombok/ValInFor.java create mode 100644 test/transform/resource/after-delombok/ValLessSimple.java create mode 100644 test/transform/resource/after-delombok/ValSimple.java create mode 100644 test/transform/resource/after-delombok/ValWeirdTypes.java create mode 100644 test/transform/resource/before/ValComplex.java create mode 100644 test/transform/resource/before/ValErrors.java create mode 100644 test/transform/resource/before/ValInFor.java create mode 100644 test/transform/resource/before/ValLessSimple.java create mode 100644 test/transform/resource/before/ValSimple.java create mode 100644 test/transform/resource/before/ValWeirdTypes.java create mode 100644 test/transform/resource/messages-delombok/ValErrors.java.messages (limited to 'src') diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java new file mode 100644 index 00000000..6c60b11e --- /dev/null +++ b/src/core/lombok/javac/JavacResolution.java @@ -0,0 +1,480 @@ +package lombok.javac; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.lang.reflect.Field; +import java.util.ArrayDeque; +import java.util.Map; + +import javax.lang.model.type.TypeKind; +import javax.tools.DiagnosticListener; + +import com.sun.tools.javac.code.BoundKind; +import com.sun.tools.javac.code.Symbol.TypeSymbol; +import com.sun.tools.javac.code.Type.CapturedType; +import com.sun.tools.javac.code.Type.ClassType; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.comp.Attr; +import com.sun.tools.javac.comp.AttrContext; +import com.sun.tools.javac.comp.Enter; +import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.comp.MemberEnter; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Log; + +public class JavacResolution { + private final Attr attr; + private final LogDisabler logDisabler; + + public JavacResolution(Context context) { + attr = Attr.instance(context); + logDisabler = new LogDisabler(context); + } + /** + * During resolution, the resolver will emit resolution errors, but without appropriate file names and line numbers. If these resolution errors stick around + * then they will be generated AGAIN, this time with proper names and line numbers, at the end. Therefore, we want to suppress the logger. + */ + private static final class LogDisabler { + private final Log log; + private static final Field errWriterField, warnWriterField, noticeWriterField, dumpOnErrorField, promptOnErrorField, diagnosticListenerField; + private PrintWriter errWriter, warnWriter, noticeWriter; + private Boolean dumpOnError, promptOnError; + private DiagnosticListener contextDiagnosticListener, logDiagnosticListener; + private final Context context; + + // If this is true, the fields changed. Better to print weird error messages than to fail outright. + private static final boolean dontBother; + + static { + boolean z; + Field a = null, b = null, c = null, d = null, e = null, f = null; + try { + a = Log.class.getDeclaredField("errWriter"); + b = Log.class.getDeclaredField("warnWriter"); + c = Log.class.getDeclaredField("noticeWriter"); + d = Log.class.getDeclaredField("dumpOnError"); + e = Log.class.getDeclaredField("promptOnError"); + f = Log.class.getDeclaredField("diagListener"); + z = false; + a.setAccessible(true); + b.setAccessible(true); + c.setAccessible(true); + d.setAccessible(true); + e.setAccessible(true); + f.setAccessible(true); + } catch (Exception x) { + z = true; + } + + errWriterField = a; + warnWriterField = b; + noticeWriterField = c; + dumpOnErrorField = d; + promptOnErrorField = e; + diagnosticListenerField = f; + dontBother = z; + } + + LogDisabler(Context context) { + this.log = Log.instance(context); + this.context = context; + } + + boolean disableLoggers() { + contextDiagnosticListener = context.get(DiagnosticListener.class); + context.put(DiagnosticListener.class, (DiagnosticListener) null); + if (dontBother) return false; + boolean dontBotherInstance = false; + + PrintWriter dummyWriter = new PrintWriter(new OutputStream() { + @Override public void write(int b) throws IOException { + // Do nothing on purpose + } + }); + + if (!dontBotherInstance) try { + errWriter = (PrintWriter) errWriterField.get(log); + errWriterField.set(log, dummyWriter); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + warnWriter = (PrintWriter) warnWriterField.get(log); + warnWriterField.set(log, dummyWriter); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + noticeWriter = (PrintWriter) noticeWriterField.get(log); + noticeWriterField.set(log, dummyWriter); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + dumpOnError = (Boolean) dumpOnErrorField.get(log); + dumpOnErrorField.set(log, false); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + promptOnError = (Boolean) promptOnErrorField.get(log); + promptOnErrorField.set(log, false); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (!dontBotherInstance) try { + logDiagnosticListener = (DiagnosticListener) diagnosticListenerField.get(log); + diagnosticListenerField.set(log, null); + } catch (Exception e) { + dontBotherInstance = true; + } + + if (dontBotherInstance) enableLoggers(); + return !dontBotherInstance; + } + + void enableLoggers() { + if (contextDiagnosticListener != null) { + context.put(DiagnosticListener.class, contextDiagnosticListener); + contextDiagnosticListener = null; + } + if (errWriter != null) try { + errWriterField.set(log, errWriter); + errWriter = null; + } catch (Exception e) {} + + if (warnWriter != null) try { + warnWriterField.set(log, warnWriter); + warnWriter = null; + } catch (Exception e) {} + + if (noticeWriter != null) try { + noticeWriterField.set(log, noticeWriter); + noticeWriter = null; + } catch (Exception e) {} + + if (dumpOnError != null) try { + dumpOnErrorField.set(log, dumpOnError); + dumpOnError = null; + } catch (Exception e) {} + + if (promptOnError != null) try { + promptOnErrorField.set(log, promptOnError); + promptOnError = null; + } catch (Exception e) {} + + if (logDiagnosticListener != null) try { + diagnosticListenerField.set(log, logDiagnosticListener); + logDiagnosticListener = null; + } catch (Exception e) {} + } + } + + private static final class EnvFinder extends JCTree.Visitor { + private Env env = null; + private Enter enter; + private MemberEnter memberEnter; + private JCTree copyAt = null; + + EnvFinder(Context context) { + this.enter = Enter.instance(context); + this.memberEnter = MemberEnter.instance(context); + } + + Env get() { + return env; + } + + JCTree copyAt() { + return copyAt; + } + + @Override public void visitTopLevel(JCCompilationUnit tree) { + if (copyAt != null) return; + env = enter.getTopLevelEnv(tree); + } + + @Override public void visitClassDef(JCClassDecl tree) { + if (copyAt != null) return; + // The commented out one leaves the 'lint' field unset, which causes NPEs during attrib. So, we use the other one. + //env = enter.classEnv((JCClassDecl) tree, env); + env = enter.getClassEnv(tree.sym); + } + + @Override public void visitMethodDef(JCMethodDecl tree) { + if (copyAt != null) return; + env = memberEnter.getMethodEnv(tree, env); + copyAt = tree; + } + + public void visitVarDef(JCVariableDecl tree) { + if (copyAt != null) return; + env = memberEnter.getInitEnv(tree, env); + copyAt = tree; + } + + @Override public void visitBlock(JCBlock tree) { + if (copyAt != null) return; + copyAt = tree; + } + } + +// /** +// * The {@code Env} object primarily tracks legal symbol names. i.e. its the lexical scope. To build it, we need to go from the top and drill down to the current node, +// * updating the {@code Env} object at each step. This TreeVisitor does that. Requires {@code enterTrees} to be called first (this is done before processors run, normally). +// */ +// private static final class EnvChainer extends JCTree.Visitor { +// private Env env = null; +// private Enter enter; +// private MemberEnter memberEnter; +// private Attr attr; +// private JCTree target; +// private boolean blocksAreInitializers; +// +// EnvChainer(Context context) { +// this.enter = Enter.instance(context); +// this.memberEnter = MemberEnter.instance(context); +// this.attr = Attr.instance(context); +// } +// +// Env get() { +// return env; +// } +// +// @Override public void visitTopLevel(JCCompilationUnit tree) { +// env = enter.getTopLevelEnv(tree); +// } +// +// @Override public void visitClassDef(JCClassDecl tree) { +// // The commented out one leaves the 'lint' field unset, which causes NPEs during attrib. So, we use the other one. +// //env = enter.classEnv((JCClassDecl) tree, env); +// env = enter.getClassEnv(tree.sym); +// blocksAreInitializers = true; +// } +// +// @Override public void visitMethodDef(JCMethodDecl tree) { +// env = memberEnter.getMethodEnv(tree, env); +// blocksAreInitializers = false; +// if (tree.body != null) visitBlock(tree.body); +// } +// +// @Override public void visitBlock(JCBlock tree) { +// if (blocksAreInitializers) attr.attribStat(tree, env); +// for (JCStatement stat : tree.stats) { +// if (stat == target) return; +// attr.attribStat(stat, env); +// } +// } +// +// @Override public void visitTree(JCTree tree) { +// // Do nothing +// } +// +// public void setTarget(JCTree target) { +// this.target = target; +// } +// }; + + public Map resolve(JavacNode node) { + ArrayDeque stack = new ArrayDeque(); + + { + JavacNode n = node; + while (n != null) { + stack.push(n.get()); + n = n.up(); + } + } + + logDisabler.disableLoggers(); + try { + EnvFinder finder = new EnvFinder(node.getContext()); + while (!stack.isEmpty()) stack.pop().accept(finder); + + TreeMirrorMaker mirrorMaker = new TreeMirrorMaker(node); + JCTree copy = mirrorMaker.copy(finder.copyAt()); + + attrib(copy, finder.get()); + return mirrorMaker.getOriginalToCopyMap(); + } finally { + logDisabler.enableLoggers(); + } + } + + private void attrib(JCTree tree, Env env) { + if (tree instanceof JCBlock) attr.attribStat(tree, env); + else if (tree instanceof JCMethodDecl) attr.attribStat(((JCMethodDecl)tree).body, env); + else if (tree instanceof JCVariableDecl) attr.attribStat(tree, env); + else throw new IllegalStateException("Called with something that isn't a block, method decl, or variable decl"); + } + +// public void resolveUpTo(JavacNode statementNode) { +// ArrayDeque stack = new ArrayDeque(); +// +// { +// JavacNode n = statementNode; +// while (n != null) { +// stack.push(n.get()); +// n = n.up(); +// } +// } +// +// logDisabler.disableLoggers(); +// try { +// JCTree tree = stack.isEmpty() ? null : stack.pop(); +// while (!stack.isEmpty()) { +// JCTree target = stack.pop(); +// envChainer.setTarget(target); +// tree.accept(envChainer); +// tree = target; +// } +// if (tree != null) { +// envChainer.setTarget(null); +// tree.accept(envChainer); +// } +// +//// System.out.println("ATTRIBSTAT: " + attr.attribStat(statementNode.get(), envChainer.get())); +//// if (statementNode.get() instanceof JCVariableDecl) { +//// System.out.println("Force-tribbing expr"); +//// JCExpression init = ((JCVariableDecl)statementNode.get()).init; +//// System.out.println("ATTRIBEXPR: " + attr.attribExpr(init, envChainer.get(), Type.noType)); +//// System.out.println("TYPE: " + ((JCVariableDecl)statementNode.get()).init.type); +//// } +// } finally { +// logDisabler.enableLoggers(); +// } +// } +// +// public void resolveExpr(JCExpression expr) { +// logDisabler.disableLoggers(); +// try { +// attr.attribExpr(expr, envChainer.get(), Type.noType); +// } finally { +// logDisabler.enableLoggers(); +// } +// } + + public static class TypeNotConvertibleException extends Exception { + public TypeNotConvertibleException(String msg) { + super(msg); + } + } + + public static JCExpression typeToJCTree(Type type, TreeMaker maker, JavacAST ast) throws TypeNotConvertibleException { + return typeToJCTree(type, maker, ast, false); + } + + public static JCExpression createJavaLangObject(TreeMaker maker, JavacAST ast) { + JCExpression out = maker.Ident(ast.toName("java")); + out = maker.Select(out, ast.toName("lang")); + out = maker.Select(out, ast.toName("Object")); + return out; + } + + private static JCExpression typeToJCTree(Type type, TreeMaker maker, JavacAST ast, boolean allowCompound) throws TypeNotConvertibleException { + // NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too. + // -- so we write our own take on that here. + + if (type.isPrimitive()) return primitiveToJCTree(type.getKind(), maker); + if (type.isErroneous()) throw new TypeNotConvertibleException("Type cannot be resolved"); + + TypeSymbol symbol = type.asElement(); + List generics = type.getTypeArguments(); + + JCExpression replacement = null; + + if (symbol == null) throw new TypeNotConvertibleException("Null or compound type"); + + if (symbol.name.len == 0) { + // Anonymous inner class + if (type instanceof ClassType) { + List ifaces = ((ClassType)type).interfaces_field; + Type supertype = ((ClassType)type).supertype_field; + if (ifaces != null && ifaces.length() == 1) { + return typeToJCTree(ifaces.get(0), maker, ast, allowCompound); + } + if (supertype != null) return typeToJCTree(supertype, maker, ast, allowCompound); + } + throw new TypeNotConvertibleException("Anonymous inner class"); + } + + if (type instanceof CapturedType) { + if (allowCompound) { + if (type.getLowerBound() == null || type.getLowerBound().tag == TypeTags.BOT) { + if (type.getUpperBound().toString().equals("java.lang.Object")) { + return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null); + } + return maker.Wildcard(maker.TypeBoundKind(BoundKind.EXTENDS), typeToJCTree(type.getUpperBound(), maker, ast, false)); + } else { + return maker.Wildcard(maker.TypeBoundKind(BoundKind.SUPER), typeToJCTree(type.getLowerBound(), maker, ast, false)); + } + } + if (type.getUpperBound() != null) { + return typeToJCTree(type.getUpperBound(), maker, ast, allowCompound); + } + + return createJavaLangObject(maker, ast); + } + + String qName = symbol.getQualifiedName().toString(); + if (qName.isEmpty()) throw new TypeNotConvertibleException("unknown type"); + if (qName.startsWith("<")) throw new TypeNotConvertibleException(qName); + String[] baseNames = symbol.getQualifiedName().toString().split("\\."); + replacement = maker.Ident(ast.toName(baseNames[0])); + for (int i = 1; i < baseNames.length; i++) { + replacement = maker.Select(replacement, ast.toName(baseNames[i])); + } + + if (generics != null && !generics.isEmpty()) { + List args = List.nil(); + for (Type t : generics) args = args.append(typeToJCTree(t, maker, ast, true)); + replacement = maker.TypeApply(replacement, args); + } + + return replacement; + } + + private static JCExpression primitiveToJCTree(TypeKind kind, TreeMaker maker) throws TypeNotConvertibleException { + switch (kind) { + case BYTE: + return maker.TypeIdent(TypeTags.BYTE); + case CHAR: + return maker.TypeIdent(TypeTags.CHAR); + case SHORT: + return maker.TypeIdent(TypeTags.SHORT); + case INT: + return maker.TypeIdent(TypeTags.INT); + case LONG: + return maker.TypeIdent(TypeTags.LONG); + case FLOAT: + return maker.TypeIdent(TypeTags.FLOAT); + case DOUBLE: + return maker.TypeIdent(TypeTags.DOUBLE); + case BOOLEAN: + return maker.TypeIdent(TypeTags.BOOLEAN); + case VOID: + return maker.TypeIdent(TypeTags.VOID); + case NULL: + case NONE: + case OTHER: + default: + throw new TypeNotConvertibleException("Nulltype"); + } + } +} diff --git a/src/core/lombok/javac/TreeMirrorMaker.java b/src/core/lombok/javac/TreeMirrorMaker.java new file mode 100644 index 00000000..1c0b9311 --- /dev/null +++ b/src/core/lombok/javac/TreeMirrorMaker.java @@ -0,0 +1,50 @@ +package lombok.javac; + +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; + +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeCopier; +import com.sun.tools.javac.util.List; + +public class TreeMirrorMaker extends TreeCopier { + private final IdentityHashMap originalToCopy = new IdentityHashMap(); + + public TreeMirrorMaker(JavacNode node) { + super(node.getTreeMaker()); + } + + @Override public T copy(T original) { + T copy = super.copy(original); + originalToCopy.put(original, copy); + return copy; + } + + @Override public T copy(T original, Void p) { + T copy = super.copy(original, p); + originalToCopy.put(original, copy); + return copy; + } + + @Override public List copy(List originals) { + List copies = super.copy(originals); + Iterator it1 = originals.iterator(); + Iterator it2 = copies.iterator(); + while (it1.hasNext()) originalToCopy.put(it1.next(), it2.next()); + return copies; + } + + @Override public List copy(List originals, Void p) { + List copies = super.copy(originals, p); + Iterator it1 = originals.iterator(); + Iterator it2 = copies.iterator(); + while (it1.hasNext()) originalToCopy.put(it1.next(), it2.next()); + return copies; + } + + public Map getOriginalToCopyMap() { + return Collections.unmodifiableMap(originalToCopy); + } +} diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java new file mode 100644 index 00000000..a6f22093 --- /dev/null +++ b/src/core/lombok/javac/handlers/HandleVal.java @@ -0,0 +1,104 @@ +/* + * Copyright © 2010 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac.handlers; + +import lombok.javac.JavacASTAdapter; +import lombok.javac.JavacASTVisitor; +import lombok.javac.JavacNode; +import lombok.javac.JavacResolution; + +import org.mangosdk.spi.ProviderFor; + +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; + +@ProviderFor(JavacASTVisitor.class) +public class HandleVal extends JavacASTAdapter { + @Override public boolean isResolutionBased() { + return true; + } + + @Override public void visitLocal(JavacNode localNode, JCVariableDecl local) { + if (local.vartype != null && local.vartype.toString().equals("val")) { + JCExpression rhsOfEnhancedForLoop = null; + if (local.init == null) { + JCTree parentRaw = localNode.directUp().get(); + if (parentRaw instanceof JCEnhancedForLoop) { + JCEnhancedForLoop efl = (JCEnhancedForLoop) parentRaw; + if (efl.var == local) rhsOfEnhancedForLoop = efl.expr; + } + } + + if (rhsOfEnhancedForLoop == null && local.init == null) { + localNode.addError("'val' on a local variable requires an initializer expression"); + return; + } + + local.mods.flags |= Flags.FINAL; + JCExpression oldVarType = local.vartype; + local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst()); + + Type type; + try { + if (rhsOfEnhancedForLoop == null) { + if (local.init.type == null) { + JavacResolution resolver = new JavacResolution(localNode.getContext()); + type = ((JCExpression) resolver.resolve(localNode).get(local.init)).type; + } else { + type = local.init.type; + } + } else { + if (rhsOfEnhancedForLoop.type == null) { + JavacResolution resolver = new JavacResolution(localNode.getContext()); + type = ((JCExpression) resolver.resolve(localNode.directUp()).get(rhsOfEnhancedForLoop)).type; + } else { + type = rhsOfEnhancedForLoop.type; + } + } + + try { + JCExpression replacement; + + if (rhsOfEnhancedForLoop != null) { + localNode.addError("For now 'val' cannot be used in enhanced for loops. Fixing this is a high priority lombok issue though!"); + return; + // TODO: Fix enhanced for loops - then uncomment a bunch of lines in test/transform/resource/*/ValInFor.java + } + replacement = JavacResolution.typeToJCTree(type, localNode.getTreeMaker(), localNode.getAst()); + if (replacement != null) local.vartype = replacement; + else local.vartype = oldVarType; + } catch (JavacResolution.TypeNotConvertibleException e) { + localNode.addError("Cannot use 'val' here because initializer expression does not have a representable type: " + e.getMessage()); + local.vartype = oldVarType; + } + } catch (RuntimeException e) { + local.vartype = oldVarType; + throw e; + } + } + // TODO search for val decls in either kind of for. + } +} diff --git a/test/transform/resource/after-delombok/ValComplex.java b/test/transform/resource/after-delombok/ValComplex.java new file mode 100644 index 00000000..54ef5c78 --- /dev/null +++ b/test/transform/resource/after-delombok/ValComplex.java @@ -0,0 +1,20 @@ +public class ValComplex { + private ValSimple field = new ValSimple(); + private static final int CONSTANT = 20; + public void testReferencingOtherFiles() { + final java.lang.String shouldBeString = field.method(); + final int shouldBeInt = CONSTANT; + final java.lang.Object lock = new Object(); + synchronized (lock) { + final int field = 20; //Shadowing + final int inner = 10; + switch (field) { + case 5: + final java.lang.String shouldBeString2 = shouldBeString; + final int innerInner = inner; + + } + } + final ValSimple shouldBeValSimple = field; //Unshadowing + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValErrors.java b/test/transform/resource/after-delombok/ValErrors.java new file mode 100644 index 00000000..5ac785ab --- /dev/null +++ b/test/transform/resource/after-delombok/ValErrors.java @@ -0,0 +1,8 @@ +public class ValErrors { + public void nullType() { + final val a = null; + } + public void unresolvableExpression() { + final val c = d; + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValInFor.java b/test/transform/resource/after-delombok/ValInFor.java new file mode 100644 index 00000000..d97ce732 --- /dev/null +++ b/test/transform/resource/after-delombok/ValInFor.java @@ -0,0 +1,20 @@ +public class ValInFor { + { + final int x = 10; + final int x2 = -1; + final java.lang.String a = "Hello"; + for (final int y = x, z = x2; y < 20; y++) { + final int q = y; + final int w = z; + final java.lang.String v = a; + } + } +/* public void enhancedFor() { + java.util.List list = java.util.Arrays.asList("Hello, World!"); + for (val shouldBeString : list) { + System.out.println(shouldBeString.toLowerCase()); + val shouldBeString2 = shouldBeString; + } + } +*/ +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValLessSimple.java b/test/transform/resource/after-delombok/ValLessSimple.java new file mode 100644 index 00000000..678b419e --- /dev/null +++ b/test/transform/resource/after-delombok/ValLessSimple.java @@ -0,0 +1,26 @@ +public class ValLessSimple { + private short field2 = 5; + private String method() { + return "method"; + } + private double method2() { + return 2.0; + } + { + System.out.println("Hello"); + final int z = 20; + final int x = 10; + final int a = z; + final short y = field2; + } + private void testVal(String param) { + final java.lang.String fieldV = field; + final int a = 10; + final int b = 20; + { + final java.lang.String methodV = method(); + final java.lang.String foo = fieldV + methodV; + } + } + private String field = "field"; +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValSimple.java b/test/transform/resource/after-delombok/ValSimple.java new file mode 100644 index 00000000..b2783eac --- /dev/null +++ b/test/transform/resource/after-delombok/ValSimple.java @@ -0,0 +1,24 @@ +public class ValSimple { + private String field = "field"; + private short field2 = 5; + + private String method() { + return "method"; + } + + private double method2() { + return 2.0; + } + + private void testVal(String param) { + final java.lang.String fieldV = field; + final java.lang.String methodV = method(); + final java.lang.String paramV = param; + final java.lang.String valOfVal = fieldV; + final java.lang.String operatorV = fieldV + valOfVal; + final short fieldW = field2; + final double methodW = method2(); + byte localVar = 3; + final int operatorW = fieldW + localVar; + } +} diff --git a/test/transform/resource/after-delombok/ValWeirdTypes.java b/test/transform/resource/after-delombok/ValWeirdTypes.java new file mode 100644 index 00000000..66212906 --- /dev/null +++ b/test/transform/resource/after-delombok/ValWeirdTypes.java @@ -0,0 +1,47 @@ +import java.util.*; +public class ValWeirdTypes { + private final List fieldList; + public void testGenerics() { + List list = new ArrayList(); + list.add("Hello, World!"); + final java.lang.String shouldBeString = list.get(0); + final java.util.List shouldBeListOfString = list; + final java.util.List shouldBeListOfStringToo = Arrays.asList("hello", "world"); + final java.lang.String shouldBeString2 = shouldBeListOfString.get(0); + } + public void testGenericsInference() { + final java.util.List huh = Collections.emptyList(); + final java.util.List huh2 = Collections.emptyList(); + } + public void testPrimitives() { + final int x = 10; + final long y = 5 + 3L; + } + public void testAnonymousInnerClass() { + final java.lang.Runnable y = new Runnable(){ + public void run() { + } + }; + } + public void testTypeParams(List param) { + final T t = param.get(0); + final Z z = fieldList.get(0); + final java.util.List k = param; + final java.util.List y = fieldList; + } + public void testBounds(List lower, List upper) { + final java.lang.Number a = lower.get(0); + final java.lang.Object b = upper.get(0); + final java.util.List c = lower; + final java.util.List d = upper; + List unbound = lower; + final java.util.List e = unbound; + } + public void testCompound() { + final java.util.ArrayList a = new ArrayList(); + final java.util.Vector b = new Vector(); + final boolean c = 1 < System.currentTimeMillis(); + final java.util.AbstractList d = c ? a : b; + java.util.RandomAccess confirm = c ? a : b; + } +} \ No newline at end of file diff --git a/test/transform/resource/before/ValComplex.java b/test/transform/resource/before/ValComplex.java new file mode 100644 index 00000000..5f718003 --- /dev/null +++ b/test/transform/resource/before/ValComplex.java @@ -0,0 +1,20 @@ +public class ValComplex { + private ValSimple field = new ValSimple(); + private static final int CONSTANT = 20; + + public void testReferencingOtherFiles() { + val shouldBeString = field.method(); + val shouldBeInt = CONSTANT; + val lock = new Object(); + synchronized (lock) { + val field = 20; //Shadowing + val inner = 10; + switch (field) { + case 5: + val shouldBeString2 = shouldBeString; + val innerInner = inner; + } + } + val shouldBeValSimple = field; //Unshadowing + } +} \ No newline at end of file diff --git a/test/transform/resource/before/ValErrors.java b/test/transform/resource/before/ValErrors.java new file mode 100644 index 00000000..742bca6d --- /dev/null +++ b/test/transform/resource/before/ValErrors.java @@ -0,0 +1,9 @@ +public class ValErrors { + public void nullType() { + val a = null; + } + + public void unresolvableExpression() { + val c = d; + } +} \ No newline at end of file diff --git a/test/transform/resource/before/ValInFor.java b/test/transform/resource/before/ValInFor.java new file mode 100644 index 00000000..af13540e --- /dev/null +++ b/test/transform/resource/before/ValInFor.java @@ -0,0 +1,20 @@ +public class ValInFor { + { + val x = 10; + val x2 = -1; + val a = "Hello"; + for (val y = x, z = x2; y < 20; y++) { + val q = y; + val w = z; + val v = a; + } + } + +/* public void enhancedFor() { + java.util.List list = java.util.Arrays.asList("Hello, World!"); + for (val shouldBeString : list) { + System.out.println(shouldBeString.toLowerCase()); + val shouldBeString2 = shouldBeString; + } + }*/ +} \ No newline at end of file diff --git a/test/transform/resource/before/ValLessSimple.java b/test/transform/resource/before/ValLessSimple.java new file mode 100644 index 00000000..bae7b73b --- /dev/null +++ b/test/transform/resource/before/ValLessSimple.java @@ -0,0 +1,31 @@ +public class ValLessSimple { + private short field2 = 5; + + private String method() { + return "method"; + } + + private double method2() { + return 2.0; + } + + { + System.out.println("Hello"); + val z = 20; + val x = 10; + val a = z; + val y = field2; + } + + private void testVal(String param) { + val fieldV = field; + val a = 10; + val b = 20; + { + val methodV = method(); + val foo = fieldV + methodV; + } + } + + private String field = "field"; +} diff --git a/test/transform/resource/before/ValSimple.java b/test/transform/resource/before/ValSimple.java new file mode 100644 index 00000000..15508bbc --- /dev/null +++ b/test/transform/resource/before/ValSimple.java @@ -0,0 +1,26 @@ +public class ValSimple { + private String field = "field"; + private short field2 = 5; + + private String method() { + return "method"; + } + + private double method2() { + return 2.0; + } + + private void testVal(String param) { + val fieldV = field; + val methodV = method(); + val paramV = param; + + val valOfVal = fieldV; + val operatorV = fieldV + valOfVal; + + val fieldW = field2; + val methodW = method2(); + byte localVar = 3; + val operatorW = fieldW + localVar; + } +} diff --git a/test/transform/resource/before/ValWeirdTypes.java b/test/transform/resource/before/ValWeirdTypes.java new file mode 100644 index 00000000..6f6eb9db --- /dev/null +++ b/test/transform/resource/before/ValWeirdTypes.java @@ -0,0 +1,54 @@ +import java.util.*; + +public class ValWeirdTypes { + private final List fieldList; + + public void testGenerics() { + List list = new ArrayList(); + list.add("Hello, World!"); + val shouldBeString = list.get(0); + val shouldBeListOfString = list; + val shouldBeListOfStringToo = Arrays.asList("hello", "world"); + val shouldBeString2 = shouldBeListOfString.get(0); + } + + public void testGenericsInference() { + val huh = Collections.emptyList(); + val huh2 = Collections.emptyList(); + } + + public void testPrimitives() { + val x = 10; + val y = 5 + 3L; + } + + public void testAnonymousInnerClass() { + val y = new Runnable() { + public void run() {} + }; + } + + public void testTypeParams(List param) { + val t = param.get(0); + val z = fieldList.get(0); + val k = param; + val y = fieldList; + } + + public void testBounds(List lower, List upper) { + val a = lower.get(0); + val b = upper.get(0); + val c = lower; + val d = upper; + List unbound = lower; + val e = unbound; + } + + public void testCompound() { + val a = new ArrayList(); + val b = new Vector(); + val c = 1 < System.currentTimeMillis(); + val d = c ? a : b; + java.util.RandomAccess confirm = c ? a : b; + } +} \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/ValErrors.java.messages b/test/transform/resource/messages-delombok/ValErrors.java.messages new file mode 100644 index 00000000..feba6912 --- /dev/null +++ b/test/transform/resource/messages-delombok/ValErrors.java.messages @@ -0,0 +1,2 @@ +3:21 ERROR Cannot use 'val' here because initializer expression does not have a representable type: +7:21 ERROR Cannot use 'val' here because initializer expression does not have a representable type: Type cannot be resolved -- cgit From f6b60b0cae7f8af2e4598f2bbbd72839e193a36b Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Wed, 3 Nov 2010 02:13:28 +0100 Subject: Intial support for @Log, for now only slf4j --- .../eclipse/handlers/EclipseHandlerUtil.java | 10 +- .../lombok/eclipse/handlers/HandleSlf4jLog.java | 158 +++++++++++++++++++++ .../eclipse/handlers/HandleSynchronized.java | 2 +- src/core/lombok/javac/handlers/HandleSlf4jLog.java | 114 +++++++++++++++ .../lombok/javac/handlers/HandleSynchronized.java | 2 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 15 +- src/core/lombok/slf4j/Log.java | 34 +++++ .../resource/after-delombok/LoggerSlf4j.java | 12 +- .../after-delombok/LoggerSlf4jAlreadyExists.java | 3 + .../after-delombok/LoggerSlf4jClassOfArray.java | 3 + .../after-delombok/LoggerSlf4jOnNonType.java | 4 + .../resource/after-delombok/LoggerSlf4jTypes.java | 17 +++ .../after-delombok/LoggerSlf4jWithClass.java | 12 ++ .../after-delombok/LoggerSlf4jWithPackage.java | 9 ++ test/transform/resource/after-ecj/LoggerSlf4j.java | 17 +++ .../after-ecj/LoggerSlf4jAlreadyExists.java | 6 + .../after-ecj/LoggerSlf4jClassOfArray.java | 6 + .../resource/after-ecj/LoggerSlf4jOnNonType.java | 7 + .../resource/after-ecj/LoggerSlf4jTypes.java | 29 ++++ .../resource/after-ecj/LoggerSlf4jWithClass.java | 24 ++++ .../resource/after-ecj/LoggerSlf4jWithPackage.java | 18 +++ test/transform/resource/before/LoggerSlf4j.java | 9 ++ .../resource/before/LoggerSlf4jAlreadyExists.java | 4 + .../resource/before/LoggerSlf4jClassOfArray.java | 3 + .../resource/before/LoggerSlf4jOnNonType.java | 5 + .../resource/before/LoggerSlf4jTypes.java | 18 +++ .../resource/before/LoggerSlf4jWithClass.java | 12 ++ .../resource/before/LoggerSlf4jWithPackage.java | 9 ++ .../LoggerSlf4jAlreadyExists.java.messages | 1 + .../LoggerSlf4jOnNonStaticInnerClass.java.messages | 1 + .../LoggerSlf4jOnNonType.java.messages | 1 + .../LoggerSlf4jTypes.java.messages | 2 + .../LoggerSlf4jAlreadyExists.java.messages | 1 + .../LoggerSlf4jOnNonStaticInnerClass.java.messages | 1 + .../LoggerSlf4jOnNonType.java.messages | 1 + .../messages-ecj/LoggerSlf4jTypes.java.messages | 2 + 36 files changed, 563 insertions(+), 9 deletions(-) create mode 100644 src/core/lombok/eclipse/handlers/HandleSlf4jLog.java create mode 100644 src/core/lombok/javac/handlers/HandleSlf4jLog.java create mode 100644 src/core/lombok/slf4j/Log.java create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jAlreadyExists.java create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jClassOfArray.java create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jOnNonType.java create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jTypes.java create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jWithClass.java create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jWithPackage.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4j.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jAlreadyExists.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jOnNonType.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jTypes.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jWithClass.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java create mode 100644 test/transform/resource/before/LoggerSlf4j.java create mode 100644 test/transform/resource/before/LoggerSlf4jAlreadyExists.java create mode 100644 test/transform/resource/before/LoggerSlf4jClassOfArray.java create mode 100644 test/transform/resource/before/LoggerSlf4jOnNonType.java create mode 100644 test/transform/resource/before/LoggerSlf4jTypes.java create mode 100644 test/transform/resource/before/LoggerSlf4jWithClass.java create mode 100644 test/transform/resource/before/LoggerSlf4jWithPackage.java create mode 100644 test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages create mode 100644 test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages create mode 100644 test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages create mode 100644 test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages create mode 100644 test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages create mode 100644 test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages create mode 100644 test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages create mode 100644 test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 5005752b..29937279 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -406,9 +406,17 @@ public class EclipseHandlerUtil { /** * Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}. + * The field carries the @{@link SuppressWarnings}("all") annotation. */ - public static void injectField(EclipseNode type, FieldDeclaration field) { + public static void injectFieldSuppressWarnings(EclipseNode type, FieldDeclaration field) { field.annotations = createSuppressWarningsAll(field, field.annotations); + injectField(type, field); + } + + /** + * Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}. + */ + public static void injectField(EclipseNode type, FieldDeclaration field) { TypeDeclaration parent = (TypeDeclaration) type.get(); if (parent.fields == null) { diff --git a/src/core/lombok/eclipse/handlers/HandleSlf4jLog.java b/src/core/lombok/eclipse/handlers/HandleSlf4jLog.java new file mode 100644 index 00000000..c9046260 --- /dev/null +++ b/src/core/lombok/eclipse/handlers/HandleSlf4jLog.java @@ -0,0 +1,158 @@ +/* + * Copyright © 2009 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.eclipse.handlers; + +import static lombok.eclipse.Eclipse.fromQualifiedName; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import java.lang.reflect.Modifier; +import java.util.Arrays; + +import lombok.core.AnnotationValues; +import lombok.core.AST.Kind; +import lombok.eclipse.Eclipse; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; +import lombok.slf4j.Log; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Expression; +import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; +import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.mangosdk.spi.ProviderFor; + +/** + * Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse. + */ +@ProviderFor(EclipseAnnotationHandler.class) +public class HandleSlf4jLog implements EclipseAnnotationHandler { + + @Override public boolean handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { + + String loggingClassName = annotation.getRawExpression("value"); + if (loggingClassName == null) loggingClassName = "void.class"; + if (!loggingClassName.endsWith(".class")) loggingClassName = loggingClassName + ".class"; + + EclipseNode owner = annotationNode.up(); + switch (owner.getKind()) { + case TYPE: + TypeDeclaration typeDecl = null; + if (owner.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) owner.get(); + int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; + + boolean notAClass = (modifiers & + (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; + + if (typeDecl == null || notAClass) { + annotationNode.addError("@Log is legal only on classes and enums."); + return false; + } + + + if (loggingClassName.equals("void.class")) { + loggingClassName = getSelfName(owner); + } + + return handleType(annotationNode, source, loggingClassName); + default: + annotationNode.addError("@Log is legal only on types."); + return true; + } + } + + private String getSelfName(EclipseNode type) { + String typeName = getSingleTypeName(type); + EclipseNode upType = type.up(); + while (upType.getKind() == Kind.TYPE) { + typeName = getSingleTypeName(upType) + "." + typeName; + upType = upType.up(); + } + String packageDeclaration = type.getPackageDeclaration(); + if (packageDeclaration != null) { + typeName = packageDeclaration + "." + typeName; + } + return typeName + ".class"; + } + + private String getSingleTypeName(EclipseNode type) { + TypeDeclaration typeDeclaration = (TypeDeclaration)type.get(); + char[] rawTypeName = typeDeclaration.name; + return rawTypeName == null ? "" : new String(rawTypeName); + } + + private boolean handleType(EclipseNode annotation, Annotation source, String loggingClassName) { + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + + EclipseNode typeNode = annotation.up(); + + MemberExistsResult fieldExists = fieldExists("log", typeNode); + switch (fieldExists) { + case NOT_EXISTS: + // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerLog4j.class); + + FieldDeclaration fieldDecl = new FieldDeclaration("log".toCharArray(), 0, -1); + Eclipse.setGeneratedBy(fieldDecl, source); + fieldDecl.declarationSourceEnd = -1; + fieldDecl.modifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; + + fieldDecl.type = new QualifiedTypeReference(fromQualifiedName("org.slf4j.Logger"), new long[]{p, p, p}); + Eclipse.setGeneratedBy(fieldDecl.type, source); + + MessageSend factoryMethodCall = new MessageSend(); + Eclipse.setGeneratedBy(factoryMethodCall, source); + factoryMethodCall.receiver = new QualifiedNameReference(fromQualifiedName("org.slf4j.LoggerFactory"), new long[] { p, p, p }, pS, pE); + Eclipse.setGeneratedBy(factoryMethodCall.receiver, source); + factoryMethodCall.receiver.statementEnd = pE; + factoryMethodCall.selector = "getLogger".toCharArray(); + + char[][] loggingClassNameTokens = fromQualifiedName(loggingClassName); + long[] posses = new long[loggingClassNameTokens.length]; + Arrays.fill(posses, p); + + QualifiedNameReference exRef = new QualifiedNameReference(loggingClassNameTokens, posses, pS, pE); + Eclipse.setGeneratedBy(exRef, source); + exRef.statementEnd = pE; + + factoryMethodCall.arguments = new Expression[] { exRef }; + factoryMethodCall.nameSourcePosition = p; + factoryMethodCall.sourceStart = pS; + factoryMethodCall.sourceEnd = factoryMethodCall.statementEnd = pE; + + fieldDecl.initialization = factoryMethodCall; + injectField(annotation.up(), fieldDecl); + + annotation.up().rebuild(); + + return true; + case EXISTS_BY_USER: + annotation.addWarning("Field 'log' already exists."); + } + + return true; + } +} diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java index fde36192..b77099b5 100644 --- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java +++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.java @@ -101,7 +101,7 @@ public class HandleSynchronized implements EclipseAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Log.class); + + String loggingClassName = annotation.getRawExpression("value"); + if (loggingClassName == null) loggingClassName = "void.class"; + if (!loggingClassName.endsWith(".class")) loggingClassName = loggingClassName + ".class"; + + + JavacNode owner = annotationNode.up(); + switch (owner.getKind()) { + case TYPE: + if ((((JCClassDecl)owner.get()).mods.flags & Flags.INTERFACE)!= 0) { + annotationNode.addError("@Log is legal only on classes and enums."); + return true; + } + + if (loggingClassName.equals("void.class")) { + loggingClassName = getSelfName(owner); + } + return handleType(annotationNode, loggingClassName); + default: + annotationNode.addError("@Log is legal only on types."); + return true; + } + } + + private String getSelfName(JavacNode typeNode) { + String typeName = ((JCClassDecl) typeNode.get()).name.toString(); + JavacNode upType = typeNode.up(); + while (upType.getKind() == Kind.TYPE) { + typeName = ((JCClassDecl) upType.get()).name.toString() + "." + typeName; + upType = upType.up(); + } + + String packageDeclaration = typeNode.getPackageDeclaration(); + if (packageDeclaration != null) { + typeName = packageDeclaration + "." + typeName; + } + return typeName + ".class"; + } + + private boolean handleType(JavacNode annotation, String loggerClassName) { + JavacNode typeNode = annotation.up(); + + TreeMaker maker = typeNode.getTreeMaker(); + + switch (fieldExists("log", typeNode)) { + case NOT_EXISTS: + // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerLog4j.class); + JCExpression loggerType = chainDots(maker, typeNode, "org", "slf4j", "Logger"); + JCExpression factoryMethod = chainDots(maker, typeNode, "org", "slf4j", "LoggerFactory", "getLogger"); + + JCExpression loggerName = chainDots(maker, typeNode, loggerClassName.split("\\.")); + JCMethodInvocation factoryMethodCall = maker.Apply(List.nil(), factoryMethod, List.of(loggerName)); + + JCVariableDecl fieldDecl = maker.VarDef( + maker.Modifiers(Flags.PRIVATE | Flags.FINAL | Flags.STATIC), + typeNode.toName("log"), loggerType, factoryMethodCall); + + injectField(typeNode, fieldDecl); + return true; + case EXISTS_BY_USER: + annotation.addWarning("Field 'log' already exists."); + } + + return true; + } +} diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index 2f900eb8..a095aaf1 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -89,7 +89,7 @@ public class HandleSynchronized implements JavacAnnotationHandler JCVariableDecl fieldDecl = maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)), methodNode.toName(lockName), objectType, newObjectArray); - injectField(methodNode.up(), fieldDecl); + injectFieldSuppressWarnings(methodNode.up(), fieldDecl); } if (method.body == null) return false; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 79436327..3e734f8b 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -390,15 +390,28 @@ public class JavacHandlerUtil { return call; } + /** + * Adds the given new field declaration to the provided type AST Node. + * The field carries the @{@link SuppressWarnings}("all") annotation. + * Also takes care of updating the JavacAST. + */ + public static void injectFieldSuppressWarnings(JavacNode typeNode, JCVariableDecl field) { + injectField(typeNode, field, true); + } + /** * Adds the given new field declaration to the provided type AST Node. * * Also takes care of updating the JavacAST. */ public static void injectField(JavacNode typeNode, JCVariableDecl field) { + injectField(typeNode, field, false); + } + + private static void injectField(JavacNode typeNode, JCVariableDecl field, boolean addSuppressWarnings) { JCClassDecl type = (JCClassDecl) typeNode.get(); - addSuppressWarningsAll(field.mods, typeNode, field.pos); + if (addSuppressWarnings) addSuppressWarningsAll(field.mods, typeNode, field.pos); type.defs = type.defs.append(field); typeNode.add(field, Kind.FIELD).recursiveSetHandled(); diff --git a/src/core/lombok/slf4j/Log.java b/src/core/lombok/slf4j/Log.java new file mode 100644 index 00000000..4a82e239 --- /dev/null +++ b/src/core/lombok/slf4j/Log.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.slf4j; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Log { + + Class value() default void.class; +} diff --git a/test/transform/resource/after-delombok/LoggerSlf4j.java b/test/transform/resource/after-delombok/LoggerSlf4j.java index 0d7dee22..dae17826 100644 --- a/test/transform/resource/after-delombok/LoggerSlf4j.java +++ b/test/transform/resource/after-delombok/LoggerSlf4j.java @@ -1,6 +1,8 @@ -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class LoggerLog4j { - private static final Logger log = LoggerFactory.getLogger(LoggerLog4j.class); +class LoggerSlf4j { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4j.class); +} +class LoggerSlf4jOuter { + static class Inner { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOuter.Inner.class); + } } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4jAlreadyExists.java b/test/transform/resource/after-delombok/LoggerSlf4jAlreadyExists.java new file mode 100644 index 00000000..a7cd9409 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jAlreadyExists.java @@ -0,0 +1,3 @@ +class LoggerSlf4jAlreadyExists { + int log; +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4jClassOfArray.java b/test/transform/resource/after-delombok/LoggerSlf4jClassOfArray.java new file mode 100644 index 00000000..bcae2741 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jClassOfArray.java @@ -0,0 +1,3 @@ +class LoggerSlf4jClassOfArray { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(String[].class); +} diff --git a/test/transform/resource/after-delombok/LoggerSlf4jOnNonType.java b/test/transform/resource/after-delombok/LoggerSlf4jOnNonType.java new file mode 100644 index 00000000..4c944172 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jOnNonType.java @@ -0,0 +1,4 @@ +class LoggerSlf4jOnNonType { + void foo() { + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4jTypes.java b/test/transform/resource/after-delombok/LoggerSlf4jTypes.java new file mode 100644 index 00000000..539f46d6 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jTypes.java @@ -0,0 +1,17 @@ +interface LoggerSlf4jTypesInterface { +} +@interface LoggerSlf4jTypesAnnotation { +} +enum LoggerSlf4jTypesEnum { +; + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesEnum.class); +} +enum LoggerSlf4jTypesEnumWithElement { + FOO; + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesEnumWithElement.class); +} +interface LoggerSlf4jTypesInterfaceOuter { + class Inner { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesInterfaceOuter.Inner.class); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4jWithClass.java b/test/transform/resource/after-delombok/LoggerSlf4jWithClass.java new file mode 100644 index 00000000..5908d374 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jWithClass.java @@ -0,0 +1,12 @@ +class LoggerSlf4jWithClass { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(String.class); +} +class LoggerSlf4jWithClassList { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(java.util.List.class); +} +class LoggerSlf4jWithClassValue { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(java.lang.String.class); +} +class LoggerSlf4jWithClassVoid { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithClassVoid.class); +} diff --git a/test/transform/resource/after-delombok/LoggerSlf4jWithPackage.java b/test/transform/resource/after-delombok/LoggerSlf4jWithPackage.java new file mode 100644 index 00000000..516f858f --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jWithPackage.java @@ -0,0 +1,9 @@ +package before; +class LoggerSlf4jWithPackage { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(before.LoggerSlf4jWithPackage.class); +} +class LoggerSlf4jWithPackageOuter { + static class Inner { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(before.LoggerSlf4jWithPackageOuter.Inner.class); + } +} diff --git a/test/transform/resource/after-ecj/LoggerSlf4j.java b/test/transform/resource/after-ecj/LoggerSlf4j.java new file mode 100644 index 00000000..6a611c2b --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4j.java @@ -0,0 +1,17 @@ +@lombok.slf4j.Log class LoggerSlf4j { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4j.class); + LoggerSlf4j() { + super(); + } +} +class LoggerSlf4jOuter { + static @lombok.slf4j.Log class Inner { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOuter.Inner.class); + Inner() { + super(); + } + } + LoggerSlf4jOuter() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4jAlreadyExists.java b/test/transform/resource/after-ecj/LoggerSlf4jAlreadyExists.java new file mode 100644 index 00000000..60e83922 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jAlreadyExists.java @@ -0,0 +1,6 @@ +@lombok.slf4j.Log class LoggerSlf4jAlreadyExists { + int log; + LoggerSlf4jAlreadyExists() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java b/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java new file mode 100644 index 00000000..c8f8069d --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java @@ -0,0 +1,6 @@ +@lombok.slf4j.Log(String[].class) class LoggerSlf4jClassOfArray { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(String[].class); + LoggerSlf4jClassOfArray() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4jOnNonType.java b/test/transform/resource/after-ecj/LoggerSlf4jOnNonType.java new file mode 100644 index 00000000..83567493 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jOnNonType.java @@ -0,0 +1,7 @@ +class LoggerSlf4jOnNonType { + LoggerSlf4jOnNonType() { + super(); + } + @lombok.slf4j.Log void foo() { + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4jTypes.java b/test/transform/resource/after-ecj/LoggerSlf4jTypes.java new file mode 100644 index 00000000..88bcdae8 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jTypes.java @@ -0,0 +1,29 @@ +@lombok.slf4j.Log interface LoggerSlf4jTypesInterface { +} +@lombok.slf4j.Log @interface LoggerSlf4jTypesAnnotation { +} +@lombok.slf4j.Log enum LoggerSlf4jTypesEnum { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesEnum.class); + () { + } + LoggerSlf4jTypesEnum() { + super(); + } +} +@lombok.slf4j.Log enum LoggerSlf4jTypesEnumWithElement { + FOO(), + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesEnumWithElement.class); + () { + } + LoggerSlf4jTypesEnumWithElement() { + super(); + } +} +interface LoggerSlf4jTypesInterfaceOuter { + @lombok.slf4j.Log class Inner { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesInterfaceOuter.Inner.class); + Inner() { + super(); + } + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java b/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java new file mode 100644 index 00000000..2839cdef --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java @@ -0,0 +1,24 @@ +@lombok.slf4j.Log(String.class) class LoggerSlf4jWithClass { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(String.class); + LoggerSlf4jWithClass() { + super(); + } +} +@lombok.slf4j.Log(java.util.List.class) class LoggerSlf4jWithClassList { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(java.util.List.class); + LoggerSlf4jWithClassList() { + super(); + } +} +@lombok.slf4j.Log(value = java.lang.String.class) class LoggerSlf4jWithClassValue { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(java.lang.String.class); + LoggerSlf4jWithClassValue() { + super(); + } +} +@lombok.slf4j.Log(void.class) class LoggerSlf4jWithClassVoid { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithClassVoid.class); + LoggerSlf4jWithClassVoid() { + super(); + } +} diff --git a/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java b/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java new file mode 100644 index 00000000..efd43685 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java @@ -0,0 +1,18 @@ +package before; +@lombok.slf4j.Log class LoggerSlf4jWithPackage { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(before.LoggerSlf4jWithPackage.class); + LoggerSlf4jWithPackage() { + super(); + } +} +class LoggerSlf4jWithPackageOuter { + static @lombok.slf4j.Log class Inner { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(before.LoggerSlf4jWithPackageOuter.Inner.class); + Inner() { + super(); + } + } + LoggerSlf4jWithPackageOuter() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4j.java b/test/transform/resource/before/LoggerSlf4j.java new file mode 100644 index 00000000..78a33fe4 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4j.java @@ -0,0 +1,9 @@ +@lombok.slf4j.Log +class LoggerSlf4j { +} +class LoggerSlf4jOuter { + @lombok.slf4j.Log + static class Inner { + + } +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4jAlreadyExists.java b/test/transform/resource/before/LoggerSlf4jAlreadyExists.java new file mode 100644 index 00000000..d0b26482 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jAlreadyExists.java @@ -0,0 +1,4 @@ +@lombok.slf4j.Log +class LoggerSlf4jAlreadyExists { + int log; +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4jClassOfArray.java b/test/transform/resource/before/LoggerSlf4jClassOfArray.java new file mode 100644 index 00000000..34394f13 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jClassOfArray.java @@ -0,0 +1,3 @@ +@lombok.slf4j.Log(String[].class) +class LoggerSlf4jClassOfArray { +} diff --git a/test/transform/resource/before/LoggerSlf4jOnNonType.java b/test/transform/resource/before/LoggerSlf4jOnNonType.java new file mode 100644 index 00000000..06c8b059 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jOnNonType.java @@ -0,0 +1,5 @@ +class LoggerSlf4jOnNonType { + @lombok.slf4j.Log + void foo() { + } +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4jTypes.java b/test/transform/resource/before/LoggerSlf4jTypes.java new file mode 100644 index 00000000..27201090 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jTypes.java @@ -0,0 +1,18 @@ +@lombok.slf4j.Log +interface LoggerSlf4jTypesInterface { +} +@lombok.slf4j.Log +@interface LoggerSlf4jTypesAnnotation { +} +@lombok.slf4j.Log +enum LoggerSlf4jTypesEnum { +} +@lombok.slf4j.Log +enum LoggerSlf4jTypesEnumWithElement { + FOO; +} +interface LoggerSlf4jTypesInterfaceOuter { + @lombok.slf4j.Log + class Inner { + } +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4jWithClass.java b/test/transform/resource/before/LoggerSlf4jWithClass.java new file mode 100644 index 00000000..0005d1f5 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jWithClass.java @@ -0,0 +1,12 @@ +@lombok.slf4j.Log(String.class) +class LoggerSlf4jWithClass { +} +@lombok.slf4j.Log(java.util.List.class) +class LoggerSlf4jWithClassList { +} +@lombok.slf4j.Log(value = java.lang.String.class) +class LoggerSlf4jWithClassValue { +} +@lombok.slf4j.Log(void.class) +class LoggerSlf4jWithClassVoid { +} diff --git a/test/transform/resource/before/LoggerSlf4jWithPackage.java b/test/transform/resource/before/LoggerSlf4jWithPackage.java new file mode 100644 index 00000000..db6e8939 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jWithPackage.java @@ -0,0 +1,9 @@ +package before; +@lombok.slf4j.Log +class LoggerSlf4jWithPackage { +} +class LoggerSlf4jWithPackageOuter { + @lombok.slf4j.Log + static class Inner { + } +} \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages new file mode 100644 index 00000000..ede6defa --- /dev/null +++ b/test/transform/resource/messages-delombok/LoggerSlf4jAlreadyExists.java.messages @@ -0,0 +1 @@ +1:1 WARNING Field 'log' already exists. diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages new file mode 100644 index 00000000..e0bbdb2a --- /dev/null +++ b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonStaticInnerClass.java.messages @@ -0,0 +1 @@ +2:9 ERROR @Log is not legal on non-static inner classes. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages new file mode 100644 index 00000000..9143d4bc --- /dev/null +++ b/test/transform/resource/messages-delombok/LoggerSlf4jOnNonType.java.messages @@ -0,0 +1 @@ +2:9 ERROR @Log is legal only on types. \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages new file mode 100644 index 00000000..ba97e38f --- /dev/null +++ b/test/transform/resource/messages-delombok/LoggerSlf4jTypes.java.messages @@ -0,0 +1,2 @@ +1:1 ERROR @Log is legal only on classes and enums. +4:1 ERROR @Log is legal only on classes and enums. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages new file mode 100644 index 00000000..f03c7660 --- /dev/null +++ b/test/transform/resource/messages-ecj/LoggerSlf4jAlreadyExists.java.messages @@ -0,0 +1 @@ +1 warning Field 'log' already exists. diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages new file mode 100644 index 00000000..e0bbdb2a --- /dev/null +++ b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonStaticInnerClass.java.messages @@ -0,0 +1 @@ +2:9 ERROR @Log is not legal on non-static inner classes. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages new file mode 100644 index 00000000..4a446f28 --- /dev/null +++ b/test/transform/resource/messages-ecj/LoggerSlf4jOnNonType.java.messages @@ -0,0 +1 @@ +2 error @Log is legal only on types. \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages new file mode 100644 index 00000000..42236c7c --- /dev/null +++ b/test/transform/resource/messages-ecj/LoggerSlf4jTypes.java.messages @@ -0,0 +1,2 @@ +1 error @Log is legal only on classes and enums. +4 error @Log is legal only on classes and enums. \ No newline at end of file -- cgit From c3eddf66cfb16d5d27c7a9562ea539344bfcb2d6 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 13:30:22 +0100 Subject: Added support for Log4J, Commons and JUL in the javac handler --- src/core/lombok/commons/Log.java | 34 +++ src/core/lombok/javac/handlers/HandleLog.java | 236 +++++++++++++++++++++ src/core/lombok/javac/handlers/HandleSlf4jLog.java | 114 ---------- .../lombok/javac/handlers/JavacHandlerUtil.java | 15 ++ src/core/lombok/jul/Log.java | 34 +++ src/core/lombok/log4j/Log.java | 34 +++ .../resource/after-delombok/LoggerCommons.java | 11 +- .../resource/after-delombok/LoggerJul.java | 10 +- .../resource/after-delombok/LoggerLog4j.java | 10 +- test/transform/resource/before/LoggerCommons.java | 11 + test/transform/resource/before/LoggerJul.java | 11 + test/transform/resource/before/LoggerLog4j.java | 11 + 12 files changed, 407 insertions(+), 124 deletions(-) create mode 100644 src/core/lombok/commons/Log.java create mode 100644 src/core/lombok/javac/handlers/HandleLog.java delete mode 100644 src/core/lombok/javac/handlers/HandleSlf4jLog.java create mode 100644 src/core/lombok/jul/Log.java create mode 100644 src/core/lombok/log4j/Log.java create mode 100644 test/transform/resource/before/LoggerCommons.java create mode 100644 test/transform/resource/before/LoggerJul.java create mode 100644 test/transform/resource/before/LoggerLog4j.java (limited to 'src') diff --git a/src/core/lombok/commons/Log.java b/src/core/lombok/commons/Log.java new file mode 100644 index 00000000..974979b7 --- /dev/null +++ b/src/core/lombok/commons/Log.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.commons; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Log { + + Class value() default void.class; +} diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java new file mode 100644 index 00000000..abeca18e --- /dev/null +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -0,0 +1,236 @@ +/* + * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac.handlers; + +import static lombok.javac.handlers.JavacHandlerUtil.*; + +import java.lang.annotation.Annotation; + +import lombok.core.AnnotationValues; +import lombok.core.AST.Kind; +import lombok.javac.JavacAnnotationHandler; +import lombok.javac.JavacNode; + +import org.mangosdk.spi.ProviderFor; + +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.util.List; + +public class HandleLog { + + private HandleLog() { + throw new UnsupportedOperationException(); + } + + public static boolean processAnnotation(LoggingFramework framework, AnnotationValues annotation, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, framework.getAnnotationClass()); + + String loggingClassName = annotation.getRawExpression("value"); + if (loggingClassName == null) loggingClassName = "void"; + if (loggingClassName.endsWith(".class")) loggingClassName = loggingClassName.substring(0, loggingClassName.length() - 6); + + JavacNode typeNode = annotationNode.up(); + switch (typeNode.getKind()) { + case TYPE: + if ((((JCClassDecl)typeNode.get()).mods.flags & Flags.INTERFACE)!= 0) { + annotationNode.addError("@Log is legal only on classes and enums."); + return true; + } + + if (fieldExists("log", typeNode)!= MemberExistsResult.NOT_EXISTS) { + annotationNode.addWarning("Field 'log' already exists."); + return true; + } + + if (loggingClassName.equals("void")) { + loggingClassName = getSelfName(typeNode); + } + createField(typeNode, loggingClassName, framework); + return true; + default: + annotationNode.addError("@Log is legal only on types."); + return true; + } + } + + private static String getSelfName(JavacNode typeNode) { + String typeName = ((JCClassDecl) typeNode.get()).name.toString(); + JavacNode upType = typeNode.up(); + while (upType.getKind() == Kind.TYPE) { + typeName = ((JCClassDecl) upType.get()).name.toString() + "." + typeName; + upType = upType.up(); + } + + String packageDeclaration = typeNode.getPackageDeclaration(); + if (packageDeclaration != null) { + typeName = packageDeclaration + "." + typeName; + } + return typeName; + } + + private static boolean createField(JavacNode typeNode, String loggerClassName, LoggingFramework framework) { + TreeMaker maker = typeNode.getTreeMaker(); + + // private static final log = (); + JCExpression loggerType = chainDotsString(maker, typeNode, framework.getLoggerTypeName()); + JCExpression factoryMethod = chainDotsString(maker, typeNode, framework.getLoggerFactoryMethodName()); + + JCExpression loggerName = framework.createFactoryParameter(typeNode, loggerClassName); + JCMethodInvocation factoryMethodCall = maker.Apply(List.nil(), factoryMethod, List.of(loggerName)); + + JCVariableDecl fieldDecl = maker.VarDef( + maker.Modifiers(Flags.PRIVATE | Flags.FINAL | Flags.STATIC), + typeNode.toName("log"), loggerType, factoryMethodCall); + + injectField(typeNode, fieldDecl); + return true; + } + + static interface LoggingFramework { + Class getAnnotationClass(); + String getLoggerTypeName(); + String getLoggerFactoryMethodName(); + JCExpression createFactoryParameter(JavacNode typeNode, String typeName); + } + + // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); + private static LoggingFramework COMMONS = new LoggingFramework() { + @Override public Class getAnnotationClass() { + return lombok.jul.Log.class; + } + + @Override public String getLoggerTypeName() { + return "org.apache.commons.logging.Log"; + } + + @Override public String getLoggerFactoryMethodName() { + return "org.apache.commons.logging.LogFactory.getLog"; + } + + @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { + return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); + } + }; + + /** + * Handles the {@link lombok.commons.Log} annotation for javac. + */ + @ProviderFor(JavacAnnotationHandler.class) + public static class HandleCommonsLog implements JavacAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + return processAnnotation(COMMONS, annotation, annotationNode); + } + } + + // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("TargetType"); + private static LoggingFramework JUL = new LoggingFramework() { + @Override public Class getAnnotationClass() { + return lombok.jul.Log.class; + } + + @Override public String getLoggerTypeName() { + return "java.util.logging.Logger"; + } + + @Override public String getLoggerFactoryMethodName() { + return "java.util.logging.Logger.getLogger"; + } + + @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { + return typeNode.getTreeMaker().Literal(typeName); + } + }; + + /** + * Handles the {@link lombok.jul.Log} annotation for javac. + */ + @ProviderFor(JavacAnnotationHandler.class) + public static class HandleJulLog implements JavacAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + return processAnnotation(JUL, annotation, annotationNode); + } + } + + // private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TargetType.class); + private static LoggingFramework LOG4J = new LoggingFramework() { + @Override public Class getAnnotationClass() { + return lombok.jul.Log.class; + } + + @Override public String getLoggerTypeName() { + return "org.apache.log4j.Logger"; + } + + @Override public String getLoggerFactoryMethodName() { + return "org.apache.log4j.Logger.getLogger"; + } + + @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { + return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); + } + }; + + /** + * Handles the {@link lombok.log4j.Log} annotation for javac. + */ + @ProviderFor(JavacAnnotationHandler.class) + public static class HandleLog4jLog implements JavacAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + return processAnnotation(LOG4J, annotation, annotationNode); + } + } + + // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TargetType.class); + private static LoggingFramework SLF4J = new LoggingFramework() { + @Override public Class getAnnotationClass() { + return lombok.slf4j.Log.class; + } + + @Override public String getLoggerTypeName() { + return "org.slf4j.Logger"; + } + + @Override public String getLoggerFactoryMethodName() { + return "org.slf4j.LoggerFactory.getLogger"; + } + + @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { + return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); + } + }; + + /** + * Handles the {@link lombok.slf4j.Log} annotation for javac. + */ + @ProviderFor(JavacAnnotationHandler.class) + public static class HandleSlf4jLog implements JavacAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + return processAnnotation(SLF4J, annotation, annotationNode); + } + } +} diff --git a/src/core/lombok/javac/handlers/HandleSlf4jLog.java b/src/core/lombok/javac/handlers/HandleSlf4jLog.java deleted file mode 100644 index 01e0b69e..00000000 --- a/src/core/lombok/javac/handlers/HandleSlf4jLog.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.javac.handlers; - -import static lombok.javac.handlers.JavacHandlerUtil.*; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.javac.JavacAnnotationHandler; -import lombok.javac.JavacNode; -import lombok.slf4j.Log; - -import org.mangosdk.spi.ProviderFor; - -import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.tree.TreeMaker; -import com.sun.tools.javac.tree.JCTree.JCAnnotation; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; -import com.sun.tools.javac.tree.JCTree.JCExpression; -import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.util.List; - -/** - * Handles the {@code lombok.slf4j.Log} annotation for javac. - */ -@ProviderFor(JavacAnnotationHandler.class) -public class HandleSlf4jLog implements JavacAnnotationHandler { - @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { - markAnnotationAsProcessed(annotationNode, Log.class); - - String loggingClassName = annotation.getRawExpression("value"); - if (loggingClassName == null) loggingClassName = "void.class"; - if (!loggingClassName.endsWith(".class")) loggingClassName = loggingClassName + ".class"; - - - JavacNode owner = annotationNode.up(); - switch (owner.getKind()) { - case TYPE: - if ((((JCClassDecl)owner.get()).mods.flags & Flags.INTERFACE)!= 0) { - annotationNode.addError("@Log is legal only on classes and enums."); - return true; - } - - if (loggingClassName.equals("void.class")) { - loggingClassName = getSelfName(owner); - } - return handleType(annotationNode, loggingClassName); - default: - annotationNode.addError("@Log is legal only on types."); - return true; - } - } - - private String getSelfName(JavacNode typeNode) { - String typeName = ((JCClassDecl) typeNode.get()).name.toString(); - JavacNode upType = typeNode.up(); - while (upType.getKind() == Kind.TYPE) { - typeName = ((JCClassDecl) upType.get()).name.toString() + "." + typeName; - upType = upType.up(); - } - - String packageDeclaration = typeNode.getPackageDeclaration(); - if (packageDeclaration != null) { - typeName = packageDeclaration + "." + typeName; - } - return typeName + ".class"; - } - - private boolean handleType(JavacNode annotation, String loggerClassName) { - JavacNode typeNode = annotation.up(); - - TreeMaker maker = typeNode.getTreeMaker(); - - switch (fieldExists("log", typeNode)) { - case NOT_EXISTS: - // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerLog4j.class); - JCExpression loggerType = chainDots(maker, typeNode, "org", "slf4j", "Logger"); - JCExpression factoryMethod = chainDots(maker, typeNode, "org", "slf4j", "LoggerFactory", "getLogger"); - - JCExpression loggerName = chainDots(maker, typeNode, loggerClassName.split("\\.")); - JCMethodInvocation factoryMethodCall = maker.Apply(List.nil(), factoryMethod, List.of(loggerName)); - - JCVariableDecl fieldDecl = maker.VarDef( - maker.Modifiers(Flags.PRIVATE | Flags.FINAL | Flags.STATIC), - typeNode.toName("log"), loggerType, factoryMethodCall); - - injectField(typeNode, fieldDecl); - return true; - case EXISTS_BY_USER: - annotation.addWarning("Field 'log' already exists."); - } - - return true; - } -} diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 3e734f8b..5dacf2ca 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -489,6 +489,21 @@ public class JavacHandlerUtil { return e; } + + + /** + * In javac, dotted access of any kind, from {@code java.lang.String} to {@code var.methodName} + * is represented by a fold-left of {@code Select} nodes with the leftmost string represented by + * a {@code Ident} node. This method generates such an expression. + * + * For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]). + * + * @see com.sun.tools.javac.tree.JCTree.JCIdent + * @see com.sun.tools.javac.tree.JCTree.JCFieldAccess + */ + public static JCExpression chainDotsString(TreeMaker maker, JavacNode node, String elems) { + return chainDots(maker, node, elems.split("\\.")); + } /** * Searches the given field node for annotations and returns each one that matches the provided regular expression pattern. diff --git a/src/core/lombok/jul/Log.java b/src/core/lombok/jul/Log.java new file mode 100644 index 00000000..5d41d1df --- /dev/null +++ b/src/core/lombok/jul/Log.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.jul; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Log { + + Class value() default void.class; +} diff --git a/src/core/lombok/log4j/Log.java b/src/core/lombok/log4j/Log.java new file mode 100644 index 00000000..6a0e6b0a --- /dev/null +++ b/src/core/lombok/log4j/Log.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.log4j; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface Log { + + Class value() default void.class; +} diff --git a/test/transform/resource/after-delombok/LoggerCommons.java b/test/transform/resource/after-delombok/LoggerCommons.java index 686ab889..a55aa336 100644 --- a/test/transform/resource/after-delombok/LoggerCommons.java +++ b/test/transform/resource/after-delombok/LoggerCommons.java @@ -1,6 +1,9 @@ -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - class LoggerCommons { - private static final Log log = LogFactory.getLog(LoggerCommons.class); + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LoggerCommons.class); +} +class LoggerCommonsString { + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(String.class); +} +class LoggerCommonsJavaLangString { + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(java.lang.String.class); } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerJul.java b/test/transform/resource/after-delombok/LoggerJul.java index de4ad914..a40bb2da 100644 --- a/test/transform/resource/after-delombok/LoggerJul.java +++ b/test/transform/resource/after-delombok/LoggerJul.java @@ -1,5 +1,9 @@ -import java.util.logging.Logger; - class LoggerJul { - private static final Logger log = Logger.getLogger("LoggerJul"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("LoggerJul"); +} +class LoggerJulString { + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("String"); +} +class LoggerJulJavaLangString { + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("java.lang.String"); } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerLog4j.java b/test/transform/resource/after-delombok/LoggerLog4j.java index 33f90278..e946c858 100644 --- a/test/transform/resource/after-delombok/LoggerLog4j.java +++ b/test/transform/resource/after-delombok/LoggerLog4j.java @@ -1,5 +1,9 @@ -import org.apache.log4j.Logger; - class LoggerLog4j { - private static final Logger log = Logger.getLogger(LoggerLog4j.class); + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoggerLog4j.class); +} +class LoggerLog4jString { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(String.class); +} +class LoggerLog4jJavaLangString { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(java.lang.String.class); } \ No newline at end of file diff --git a/test/transform/resource/before/LoggerCommons.java b/test/transform/resource/before/LoggerCommons.java new file mode 100644 index 00000000..97c91ef0 --- /dev/null +++ b/test/transform/resource/before/LoggerCommons.java @@ -0,0 +1,11 @@ +@lombok.commons.Log +class LoggerCommons { +} + +@lombok.commons.Log(String.class) +class LoggerCommonsString { +} + +@lombok.commons.Log(java.lang.String.class) +class LoggerCommonsJavaLangString { +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerJul.java b/test/transform/resource/before/LoggerJul.java new file mode 100644 index 00000000..1e3313cb --- /dev/null +++ b/test/transform/resource/before/LoggerJul.java @@ -0,0 +1,11 @@ +@lombok.jul.Log +class LoggerJul { +} + +@lombok.jul.Log(String.class) +class LoggerJulString { +} + +@lombok.jul.Log(java.lang.String.class) +class LoggerJulJavaLangString { +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerLog4j.java b/test/transform/resource/before/LoggerLog4j.java new file mode 100644 index 00000000..33a876c9 --- /dev/null +++ b/test/transform/resource/before/LoggerLog4j.java @@ -0,0 +1,11 @@ +@lombok.log4j.Log +class LoggerLog4j { +} + +@lombok.log4j.Log(String.class) +class LoggerLog4jString { +} + +@lombok.log4j.Log(java.lang.String.class) +class LoggerLog4jJavaLangString { +} \ No newline at end of file -- cgit From 1346a830c11999c9ccf83831f27f163cb7537dab Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 14:16:57 +0100 Subject: Fixed typo --- src/delombok/lombok/delombok/PrettyCommentsPrinter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 16c06f50..721954d1 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -337,7 +337,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { * Traversal methods *************************************************************************/ - /** Exception to propogate IOException through visitXXX methods */ + /** Exception to propagate IOException through visitXXX methods */ private static class UncheckedIOException extends Error { static final long serialVersionUID = -4032692679158424751L; UncheckedIOException(IOException e) { -- cgit From f6bbebfbd200fab85a637e3b7939a9c1444332a3 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 14:17:22 +0100 Subject: Use an annotation instead of implementations of interfaces --- src/core/lombok/javac/handlers/HandleLog.java | 135 ++++++++++---------------- 1 file changed, 49 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index abeca18e..652fbae0 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -111,126 +111,89 @@ public class HandleLog { return true; } - static interface LoggingFramework { - Class getAnnotationClass(); - String getLoggerTypeName(); - String getLoggerFactoryMethodName(); - JCExpression createFactoryParameter(JavacNode typeNode, String typeName); - } - - // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); - private static LoggingFramework COMMONS = new LoggingFramework() { - @Override public Class getAnnotationClass() { - return lombok.jul.Log.class; - } - - @Override public String getLoggerTypeName() { - return "org.apache.commons.logging.Log"; - } - - @Override public String getLoggerFactoryMethodName() { - return "org.apache.commons.logging.LogFactory.getLog"; - } - - @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { - return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); - } - }; - /** * Handles the {@link lombok.commons.Log} annotation for javac. */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleCommonsLog implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(COMMONS, annotation, annotationNode); + return processAnnotation(LoggingFramework.COMMONS, annotation, annotationNode); } } - // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("TargetType"); - private static LoggingFramework JUL = new LoggingFramework() { - @Override public Class getAnnotationClass() { - return lombok.jul.Log.class; - } - - @Override public String getLoggerTypeName() { - return "java.util.logging.Logger"; - } - - @Override public String getLoggerFactoryMethodName() { - return "java.util.logging.Logger.getLogger"; - } - - @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { - return typeNode.getTreeMaker().Literal(typeName); - } - }; - /** * Handles the {@link lombok.jul.Log} annotation for javac. */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleJulLog implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(JUL, annotation, annotationNode); + return processAnnotation(LoggingFramework.JUL, annotation, annotationNode); } } - // private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TargetType.class); - private static LoggingFramework LOG4J = new LoggingFramework() { - @Override public Class getAnnotationClass() { - return lombok.jul.Log.class; - } - - @Override public String getLoggerTypeName() { - return "org.apache.log4j.Logger"; - } - - @Override public String getLoggerFactoryMethodName() { - return "org.apache.log4j.Logger.getLogger"; - } - - @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { - return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); - } - }; - /** * Handles the {@link lombok.log4j.Log} annotation for javac. */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleLog4jLog implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(LOG4J, annotation, annotationNode); + return processAnnotation(LoggingFramework.LOG4J, annotation, annotationNode); } } - // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TargetType.class); - private static LoggingFramework SLF4J = new LoggingFramework() { - @Override public Class getAnnotationClass() { - return lombok.slf4j.Log.class; + /** + * Handles the {@link lombok.slf4j.Log} annotation for javac. + */ + @ProviderFor(JavacAnnotationHandler.class) + public static class HandleSlf4jLog implements JavacAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + return processAnnotation(LoggingFramework.SLF4J, annotation, annotationNode); + } + } + + enum LoggingFramework { + // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); + COMMONS(lombok.jul.Log.class, "org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory.getLog"), + + // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("TargetType"); + JUL(lombok.jul.Log.class, "java.util.logging.Logger", "java.util.logging.Logger.getLogger") { + @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { + return typeNode.getTreeMaker().Literal(typeName); + } + }, + + // private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TargetType.class); + LOG4J(lombok.jul.Log.class, "org.apache.log4j.Logger", "org.apache.log4j.Logger.getLogger"), + + // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TargetType.class); + SLF4J(lombok.slf4j.Log.class, "org.slf4j.Logger", "org.slf4j.LoggerFactory.getLogger"), + + ; + + private final Class annotationClass; + private final String loggerTypeName; + private final String loggerFactoryName; + + LoggingFramework(Class annotationClass, String loggerTypeName, String loggerFactoryName) { + this.annotationClass = annotationClass; + this.loggerTypeName = loggerTypeName; + this.loggerFactoryName = loggerFactoryName; } - @Override public String getLoggerTypeName() { - return "org.slf4j.Logger"; + final Class getAnnotationClass() { + return annotationClass; } - @Override public String getLoggerFactoryMethodName() { - return "org.slf4j.LoggerFactory.getLogger"; + final String getLoggerTypeName() { + return loggerTypeName; } - @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { - return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); + final String getLoggerFactoryMethodName() { + return loggerFactoryName; } - }; - - /** - * Handles the {@link lombok.slf4j.Log} annotation for javac. - */ - @ProviderFor(JavacAnnotationHandler.class) - public static class HandleSlf4jLog implements JavacAnnotationHandler { - @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(SLF4J, annotation, annotationNode); + + JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { + return chainDotsString(typeNode.getTreeMaker(), typeNode, typeName + ".class"); } } } -- cgit From 66661b63c8becd7a9c1813815fdb09efefbf334a Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 15:36:45 +0100 Subject: Reorder parameters --- src/core/lombok/javac/handlers/HandleLog.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 652fbae0..52a308ab 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -70,7 +70,7 @@ public class HandleLog { if (loggingClassName.equals("void")) { loggingClassName = getSelfName(typeNode); } - createField(typeNode, loggingClassName, framework); + createField(framework, typeNode, loggingClassName); return true; default: annotationNode.addError("@Log is legal only on types."); @@ -93,7 +93,7 @@ public class HandleLog { return typeName; } - private static boolean createField(JavacNode typeNode, String loggerClassName, LoggingFramework framework) { + private static boolean createField(LoggingFramework framework, JavacNode typeNode, String loggerClassName) { TreeMaker maker = typeNode.getTreeMaker(); // private static final log = (); -- cgit From 8a3a656213605482bfa11f2efddf96dc1f47d16e Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 15:37:20 +0100 Subject: Add support for multiple logging frameworks in Eclipse --- src/core/lombok/eclipse/handlers/HandleLog.java | 267 +++++++++++++++++++++ .../lombok/eclipse/handlers/HandleSlf4jLog.java | 158 ------------ .../resource/after-ecj/LoggerCommons.java | 18 ++ test/transform/resource/after-ecj/LoggerJul.java | 18 ++ test/transform/resource/after-ecj/LoggerLog4j.java | 18 ++ 5 files changed, 321 insertions(+), 158 deletions(-) create mode 100644 src/core/lombok/eclipse/handlers/HandleLog.java delete mode 100644 src/core/lombok/eclipse/handlers/HandleSlf4jLog.java create mode 100644 test/transform/resource/after-ecj/LoggerCommons.java create mode 100644 test/transform/resource/after-ecj/LoggerJul.java create mode 100644 test/transform/resource/after-ecj/LoggerLog4j.java (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java new file mode 100644 index 00000000..5991fec0 --- /dev/null +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -0,0 +1,267 @@ +/* + * Copyright © 2009 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.eclipse.handlers; + +import static lombok.eclipse.Eclipse.fromQualifiedName; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import java.lang.reflect.Modifier; +import java.util.Arrays; + +import lombok.core.AnnotationValues; +import lombok.core.AST.Kind; +import lombok.eclipse.Eclipse; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Expression; +import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; +import org.eclipse.jdt.internal.compiler.ast.NameReference; +import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.StringLiteral; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.ast.TypeReference; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.mangosdk.spi.ProviderFor; + +/** + * Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse. + */ +public class HandleLog { + + public static boolean processAnnotation(LoggingFramework framework, AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { + + String loggingClassName = annotation.getRawExpression("value"); + if (loggingClassName == null) loggingClassName = "void"; + if (loggingClassName.endsWith(".class")) loggingClassName = loggingClassName.substring(0, loggingClassName.length() - 6); + + EclipseNode owner = annotationNode.up(); + switch (owner.getKind()) { + case TYPE: + TypeDeclaration typeDecl = null; + if (owner.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) owner.get(); + int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; + + boolean notAClass = (modifiers & + (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; + + if (typeDecl == null || notAClass) { + annotationNode.addError("@Log is legal only on classes and enums."); + return false; + } + + MemberExistsResult fieldExists = fieldExists("log", owner); + if (fieldExists != MemberExistsResult.NOT_EXISTS) { + annotationNode.addWarning("Field 'log' already exists."); + return true; + } + + if (loggingClassName.equals("void")) { + loggingClassName = getSelfName(owner); + } + + injectField(owner, createField(framework, source, loggingClassName)); + owner.rebuild(); + return true; + default: + annotationNode.addError("@Log is legal only on types."); + return true; + } + } + + private static String getSelfName(EclipseNode type) { + String typeName = getSingleTypeName(type); + EclipseNode upType = type.up(); + while (upType.getKind() == Kind.TYPE) { + typeName = getSingleTypeName(upType) + "." + typeName; + upType = upType.up(); + } + String packageDeclaration = type.getPackageDeclaration(); + if (packageDeclaration != null) { + typeName = packageDeclaration + "." + typeName; + } + return typeName; + } + + private static String getSingleTypeName(EclipseNode type) { + TypeDeclaration typeDeclaration = (TypeDeclaration)type.get(); + char[] rawTypeName = typeDeclaration.name; + return rawTypeName == null ? "" : new String(rawTypeName); + } + + private static FieldDeclaration createField(LoggingFramework framework, Annotation source, String loggingClassName) { + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + + // private static final log = (); + + FieldDeclaration fieldDecl = new FieldDeclaration("log".toCharArray(), 0, -1); + Eclipse.setGeneratedBy(fieldDecl, source); + fieldDecl.declarationSourceEnd = -1; + fieldDecl.modifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; + + fieldDecl.type = createTypeReference(framework.getLoggerTypeName(), source); + + MessageSend factoryMethodCall = new MessageSend(); + Eclipse.setGeneratedBy(factoryMethodCall, source); + + factoryMethodCall.receiver = createNameReference(framework.getLoggerFactoryTypeName(), source); + factoryMethodCall.selector = framework.getLoggerFactoryMethodName().toCharArray(); + + Expression parameter = framework.createFactoryParameter(loggingClassName, source); + + factoryMethodCall.arguments = new Expression[] { parameter }; + factoryMethodCall.nameSourcePosition = p; + factoryMethodCall.sourceStart = pS; + factoryMethodCall.sourceEnd = factoryMethodCall.statementEnd = pE; + + fieldDecl.initialization = factoryMethodCall; + + return fieldDecl; + } + + private static TypeReference createTypeReference(String typeName, Annotation source) { + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + + char[][] typeNameTokens = fromQualifiedName(typeName); + long[] pos = new long[typeNameTokens.length]; + Arrays.fill(pos, p); + + QualifiedTypeReference typeReference = new QualifiedTypeReference(typeNameTokens, pos); + Eclipse.setGeneratedBy(typeReference, source); + return typeReference; + } + + private static NameReference createNameReference(String name, Annotation source) { + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + + char[][] nameTokens = fromQualifiedName(name); + long[] pos = new long[nameTokens.length]; + Arrays.fill(pos, p); + + QualifiedNameReference nameReference = new QualifiedNameReference(nameTokens, pos, pS, pE); + nameReference.statementEnd = pE; + + Eclipse.setGeneratedBy(nameReference, source); + return nameReference; + } + + /** + * Handles the {@link lombok.commons.Log} annotation for Eclipse. + */ + @ProviderFor(EclipseAnnotationHandler.class) + public static class HandleCommonsLog implements EclipseAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { + return processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode); + } + } + + /** + * Handles the {@link lombok.jul.Log} annotation for Eclipse. + */ + @ProviderFor(EclipseAnnotationHandler.class) + public static class HandleJulLog implements EclipseAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { + return processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode); + } + } + + /** + * Handles the {@link lombok.log4j.Log} annotation for Eclipse. + */ + @ProviderFor(EclipseAnnotationHandler.class) + public static class HandleLog4jLog implements EclipseAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { + return processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode); + } + } + + /** + * Handles the {@link lombok.slf4j.Log} annotation for Eclipse. + */ + @ProviderFor(EclipseAnnotationHandler.class) + public static class HandleSlf4jLog implements EclipseAnnotationHandler { + @Override public boolean handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { + return processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode); + } + } + + enum LoggingFramework { + // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); + COMMONS(lombok.jul.Log.class, "org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory", "getLog"), + + // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("TargetType"); + JUL(lombok.jul.Log.class, "java.util.logging.Logger", "java.util.logging.Logger", "getLogger") { + @Override public Expression createFactoryParameter(String typeName, Annotation source) { + Expression current = new StringLiteral(typeName.toCharArray(), source.sourceStart, source.sourceEnd, 0); + Eclipse.setGeneratedBy(current, source); + return current; + } + }, + + // private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TargetType.class); + LOG4J(lombok.jul.Log.class, "org.apache.log4j.Logger", "org.apache.log4j.Logger", "getLogger"), + + // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TargetType.class); + SLF4J(lombok.slf4j.Log.class, "org.slf4j.Logger", "org.slf4j.LoggerFactory", "getLogger"), + + ; + + private final Class annotationClass; + private final String loggerTypeName; + private final String loggerFactoryTypeName; + private final String loggerFactoryMethodName; + + LoggingFramework(Class annotationClass, String loggerTypeName, String loggerFactoryTypeName, String loggerFactoryMethodName) { + this.annotationClass = annotationClass; + this.loggerTypeName = loggerTypeName; + this.loggerFactoryTypeName = loggerFactoryTypeName; + this.loggerFactoryMethodName = loggerFactoryMethodName; + } + + final Class getAnnotationClass() { + return annotationClass; + } + + final String getLoggerTypeName() { + return loggerTypeName; + } + + final String getLoggerFactoryTypeName() { + return loggerFactoryTypeName; + } + + final String getLoggerFactoryMethodName() { + return loggerFactoryMethodName; + } + + Expression createFactoryParameter(String typeName, Annotation source){ + return createNameReference(typeName + ".class", source); + }; + } +} diff --git a/src/core/lombok/eclipse/handlers/HandleSlf4jLog.java b/src/core/lombok/eclipse/handlers/HandleSlf4jLog.java deleted file mode 100644 index c9046260..00000000 --- a/src/core/lombok/eclipse/handlers/HandleSlf4jLog.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.eclipse.handlers; - -import static lombok.eclipse.Eclipse.fromQualifiedName; -import static lombok.eclipse.handlers.EclipseHandlerUtil.*; - -import java.lang.reflect.Modifier; -import java.util.Arrays; - -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; -import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; -import lombok.slf4j.Log; - -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.MessageSend; -import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.mangosdk.spi.ProviderFor; - -/** - * Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse. - */ -@ProviderFor(EclipseAnnotationHandler.class) -public class HandleSlf4jLog implements EclipseAnnotationHandler { - - @Override public boolean handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { - - String loggingClassName = annotation.getRawExpression("value"); - if (loggingClassName == null) loggingClassName = "void.class"; - if (!loggingClassName.endsWith(".class")) loggingClassName = loggingClassName + ".class"; - - EclipseNode owner = annotationNode.up(); - switch (owner.getKind()) { - case TYPE: - TypeDeclaration typeDecl = null; - if (owner.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) owner.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; - - if (typeDecl == null || notAClass) { - annotationNode.addError("@Log is legal only on classes and enums."); - return false; - } - - - if (loggingClassName.equals("void.class")) { - loggingClassName = getSelfName(owner); - } - - return handleType(annotationNode, source, loggingClassName); - default: - annotationNode.addError("@Log is legal only on types."); - return true; - } - } - - private String getSelfName(EclipseNode type) { - String typeName = getSingleTypeName(type); - EclipseNode upType = type.up(); - while (upType.getKind() == Kind.TYPE) { - typeName = getSingleTypeName(upType) + "." + typeName; - upType = upType.up(); - } - String packageDeclaration = type.getPackageDeclaration(); - if (packageDeclaration != null) { - typeName = packageDeclaration + "." + typeName; - } - return typeName + ".class"; - } - - private String getSingleTypeName(EclipseNode type) { - TypeDeclaration typeDeclaration = (TypeDeclaration)type.get(); - char[] rawTypeName = typeDeclaration.name; - return rawTypeName == null ? "" : new String(rawTypeName); - } - - private boolean handleType(EclipseNode annotation, Annotation source, String loggingClassName) { - int pS = source.sourceStart, pE = source.sourceEnd; - long p = (long)pS << 32 | pE; - - EclipseNode typeNode = annotation.up(); - - MemberExistsResult fieldExists = fieldExists("log", typeNode); - switch (fieldExists) { - case NOT_EXISTS: - // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerLog4j.class); - - FieldDeclaration fieldDecl = new FieldDeclaration("log".toCharArray(), 0, -1); - Eclipse.setGeneratedBy(fieldDecl, source); - fieldDecl.declarationSourceEnd = -1; - fieldDecl.modifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; - - fieldDecl.type = new QualifiedTypeReference(fromQualifiedName("org.slf4j.Logger"), new long[]{p, p, p}); - Eclipse.setGeneratedBy(fieldDecl.type, source); - - MessageSend factoryMethodCall = new MessageSend(); - Eclipse.setGeneratedBy(factoryMethodCall, source); - factoryMethodCall.receiver = new QualifiedNameReference(fromQualifiedName("org.slf4j.LoggerFactory"), new long[] { p, p, p }, pS, pE); - Eclipse.setGeneratedBy(factoryMethodCall.receiver, source); - factoryMethodCall.receiver.statementEnd = pE; - factoryMethodCall.selector = "getLogger".toCharArray(); - - char[][] loggingClassNameTokens = fromQualifiedName(loggingClassName); - long[] posses = new long[loggingClassNameTokens.length]; - Arrays.fill(posses, p); - - QualifiedNameReference exRef = new QualifiedNameReference(loggingClassNameTokens, posses, pS, pE); - Eclipse.setGeneratedBy(exRef, source); - exRef.statementEnd = pE; - - factoryMethodCall.arguments = new Expression[] { exRef }; - factoryMethodCall.nameSourcePosition = p; - factoryMethodCall.sourceStart = pS; - factoryMethodCall.sourceEnd = factoryMethodCall.statementEnd = pE; - - fieldDecl.initialization = factoryMethodCall; - injectField(annotation.up(), fieldDecl); - - annotation.up().rebuild(); - - return true; - case EXISTS_BY_USER: - annotation.addWarning("Field 'log' already exists."); - } - - return true; - } -} diff --git a/test/transform/resource/after-ecj/LoggerCommons.java b/test/transform/resource/after-ecj/LoggerCommons.java new file mode 100644 index 00000000..1d21fb66 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerCommons.java @@ -0,0 +1,18 @@ +@lombok.commons.Log class LoggerCommons { + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LoggerCommons.class); + LoggerCommons() { + super(); + } +} +@lombok.commons.Log(String.class) class LoggerCommonsString { + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(String.class); + LoggerCommonsString() { + super(); + } +} +@lombok.commons.Log(java.lang.String.class) class LoggerCommonsJavaLangString { + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(java.lang.String.class); + LoggerCommonsJavaLangString() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerJul.java b/test/transform/resource/after-ecj/LoggerJul.java new file mode 100644 index 00000000..86405ebd --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerJul.java @@ -0,0 +1,18 @@ +@lombok.jul.Log class LoggerJul { + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("LoggerJul"); + LoggerJul() { + super(); + } +} +@lombok.jul.Log(String.class) class LoggerJulString { + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("String"); + LoggerJulString() { + super(); + } +} +@lombok.jul.Log(java.lang.String.class) class LoggerJulJavaLangString { + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("java.lang.String"); + LoggerJulJavaLangString() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerLog4j.java b/test/transform/resource/after-ecj/LoggerLog4j.java new file mode 100644 index 00000000..27ad6b9c --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerLog4j.java @@ -0,0 +1,18 @@ +@lombok.log4j.Log class LoggerLog4j { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoggerLog4j.class); + LoggerLog4j() { + super(); + } +} +@lombok.log4j.Log(String.class) class LoggerLog4jString { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(String.class); + LoggerLog4jString() { + super(); + } +} +@lombok.log4j.Log(java.lang.String.class) class LoggerLog4jJavaLangString { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(java.lang.String.class); + LoggerLog4jJavaLangString() { + super(); + } +} \ No newline at end of file -- cgit From a48c335c7d8f1b361b134110219af8b0d3610101 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 16:05:06 +0100 Subject: Code cleanup --- src/core/lombok/eclipse/handlers/HandleLog.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index 5991fec0..23768226 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -47,11 +47,12 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.mangosdk.spi.ProviderFor; -/** - * Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse. - */ public class HandleLog { + private HandleLog() { + throw new UnsupportedOperationException(); + } + public static boolean processAnnotation(LoggingFramework framework, AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { String loggingClassName = annotation.getRawExpression("value"); @@ -73,8 +74,7 @@ public class HandleLog { return false; } - MemberExistsResult fieldExists = fieldExists("log", owner); - if (fieldExists != MemberExistsResult.NOT_EXISTS) { + if (fieldExists("log", owner) != MemberExistsResult.NOT_EXISTS) { annotationNode.addWarning("Field 'log' already exists."); return true; } -- cgit From 0c7b29f8e7009d1433e2386f710c78801f119ebb Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 16:41:17 +0100 Subject: Create Clinit if you create a static field and it doesn't yet exist --- .../lombok/eclipse/handlers/EclipseHandlerUtil.java | 17 +++++++++++++++++ test/transform/resource/after-ecj/LoggerCommons.java | 6 ++++++ test/transform/resource/after-ecj/LoggerJul.java | 6 ++++++ test/transform/resource/after-ecj/LoggerLog4j.java | 6 ++++++ test/transform/resource/after-ecj/LoggerSlf4j.java | 4 ++++ .../resource/after-ecj/LoggerSlf4jClassOfArray.java | 2 ++ test/transform/resource/after-ecj/LoggerSlf4jTypes.java | 2 ++ .../resource/after-ecj/LoggerSlf4jWithClass.java | 8 ++++++++ .../resource/after-ecj/LoggerSlf4jWithPackage.java | 4 ++++ .../transform/resource/after-ecj/SynchronizedPlain.java | 2 ++ 10 files changed, 57 insertions(+) (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 29937279..c37de8ea 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -23,6 +23,7 @@ package lombok.eclipse.handlers; import static lombok.eclipse.Eclipse.*; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -42,6 +43,7 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Clinit; import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; import org.eclipse.jdt.internal.compiler.ast.EqualExpression; import org.eclipse.jdt.internal.compiler.ast.Expression; @@ -429,9 +431,24 @@ public class EclipseHandlerUtil { parent.fields = newArray; } + if ((field.modifiers & Modifier.STATIC) != 0) { + if (!hasClinit(parent)) { + parent.addClinit(); + } + } + type.add(field, Kind.FIELD).recursiveSetHandled(); } + private static boolean hasClinit(TypeDeclaration parent) { + if (parent.methods == null) return false; + + for (AbstractMethodDeclaration method : parent.methods) { + if (method instanceof Clinit) return true; + } + return false; + } + /** * Inserts a method into an existing type. The type must represent a {@code TypeDeclaration}. */ diff --git a/test/transform/resource/after-ecj/LoggerCommons.java b/test/transform/resource/after-ecj/LoggerCommons.java index 1d21fb66..e5a3bf35 100644 --- a/test/transform/resource/after-ecj/LoggerCommons.java +++ b/test/transform/resource/after-ecj/LoggerCommons.java @@ -1,17 +1,23 @@ @lombok.commons.Log class LoggerCommons { private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LoggerCommons.class); + () { + } LoggerCommons() { super(); } } @lombok.commons.Log(String.class) class LoggerCommonsString { private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(String.class); + () { + } LoggerCommonsString() { super(); } } @lombok.commons.Log(java.lang.String.class) class LoggerCommonsJavaLangString { private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(java.lang.String.class); + () { + } LoggerCommonsJavaLangString() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerJul.java b/test/transform/resource/after-ecj/LoggerJul.java index 86405ebd..734d0dac 100644 --- a/test/transform/resource/after-ecj/LoggerJul.java +++ b/test/transform/resource/after-ecj/LoggerJul.java @@ -1,17 +1,23 @@ @lombok.jul.Log class LoggerJul { private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("LoggerJul"); + () { + } LoggerJul() { super(); } } @lombok.jul.Log(String.class) class LoggerJulString { private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("String"); + () { + } LoggerJulString() { super(); } } @lombok.jul.Log(java.lang.String.class) class LoggerJulJavaLangString { private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("java.lang.String"); + () { + } LoggerJulJavaLangString() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerLog4j.java b/test/transform/resource/after-ecj/LoggerLog4j.java index 27ad6b9c..64445b96 100644 --- a/test/transform/resource/after-ecj/LoggerLog4j.java +++ b/test/transform/resource/after-ecj/LoggerLog4j.java @@ -1,17 +1,23 @@ @lombok.log4j.Log class LoggerLog4j { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoggerLog4j.class); + () { + } LoggerLog4j() { super(); } } @lombok.log4j.Log(String.class) class LoggerLog4jString { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(String.class); + () { + } LoggerLog4jString() { super(); } } @lombok.log4j.Log(java.lang.String.class) class LoggerLog4jJavaLangString { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(java.lang.String.class); + () { + } LoggerLog4jJavaLangString() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerSlf4j.java b/test/transform/resource/after-ecj/LoggerSlf4j.java index 6a611c2b..2e4d65a5 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4j.java +++ b/test/transform/resource/after-ecj/LoggerSlf4j.java @@ -1,5 +1,7 @@ @lombok.slf4j.Log class LoggerSlf4j { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4j.class); + () { + } LoggerSlf4j() { super(); } @@ -7,6 +9,8 @@ class LoggerSlf4jOuter { static @lombok.slf4j.Log class Inner { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOuter.Inner.class); + () { + } Inner() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java b/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java index c8f8069d..ffec7e66 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java +++ b/test/transform/resource/after-ecj/LoggerSlf4jClassOfArray.java @@ -1,5 +1,7 @@ @lombok.slf4j.Log(String[].class) class LoggerSlf4jClassOfArray { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(String[].class); + () { + } LoggerSlf4jClassOfArray() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerSlf4jTypes.java b/test/transform/resource/after-ecj/LoggerSlf4jTypes.java index 88bcdae8..2e860ed2 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4jTypes.java +++ b/test/transform/resource/after-ecj/LoggerSlf4jTypes.java @@ -22,6 +22,8 @@ interface LoggerSlf4jTypesInterfaceOuter { @lombok.slf4j.Log class Inner { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jTypesInterfaceOuter.Inner.class); + () { + } Inner() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java b/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java index 2839cdef..fbb4b2d2 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java +++ b/test/transform/resource/after-ecj/LoggerSlf4jWithClass.java @@ -1,23 +1,31 @@ @lombok.slf4j.Log(String.class) class LoggerSlf4jWithClass { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(String.class); + () { + } LoggerSlf4jWithClass() { super(); } } @lombok.slf4j.Log(java.util.List.class) class LoggerSlf4jWithClassList { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(java.util.List.class); + () { + } LoggerSlf4jWithClassList() { super(); } } @lombok.slf4j.Log(value = java.lang.String.class) class LoggerSlf4jWithClassValue { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(java.lang.String.class); + () { + } LoggerSlf4jWithClassValue() { super(); } } @lombok.slf4j.Log(void.class) class LoggerSlf4jWithClassVoid { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithClassVoid.class); + () { + } LoggerSlf4jWithClassVoid() { super(); } diff --git a/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java b/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java index efd43685..76d19bc3 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java +++ b/test/transform/resource/after-ecj/LoggerSlf4jWithPackage.java @@ -1,6 +1,8 @@ package before; @lombok.slf4j.Log class LoggerSlf4jWithPackage { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(before.LoggerSlf4jWithPackage.class); + () { + } LoggerSlf4jWithPackage() { super(); } @@ -8,6 +10,8 @@ package before; class LoggerSlf4jWithPackageOuter { static @lombok.slf4j.Log class Inner { private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(before.LoggerSlf4jWithPackageOuter.Inner.class); + () { + } Inner() { super(); } diff --git a/test/transform/resource/after-ecj/SynchronizedPlain.java b/test/transform/resource/after-ecj/SynchronizedPlain.java index b9f032c5..8e5b6297 100644 --- a/test/transform/resource/after-ecj/SynchronizedPlain.java +++ b/test/transform/resource/after-ecj/SynchronizedPlain.java @@ -19,6 +19,8 @@ class SynchronizedPlain1 { } class SynchronizedPlain2 { private static final @java.lang.SuppressWarnings("all") java.lang.Object $LOCK = new java.lang.Object[0]; + () { + } SynchronizedPlain2() { super(); } -- cgit From 529a480ca998f7eab16ff9745e8fb08aa28072e5 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 17:39:04 +0100 Subject: Use a ClassLiteralAccess instead of a NameReference --- src/core/lombok/eclipse/handlers/HandleLog.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index 23768226..08f3e6f2 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -35,6 +35,7 @@ import lombok.eclipse.EclipseNode; import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.MessageSend; @@ -261,7 +262,10 @@ public class HandleLog { } Expression createFactoryParameter(String typeName, Annotation source){ - return createNameReference(typeName + ".class", source); + TypeReference type = createTypeReference(typeName, source); + ClassLiteralAccess result = new ClassLiteralAccess(source.sourceEnd, type); + Eclipse.setGeneratedBy(result, source); + return result; }; } } -- cgit From 59150328992339ec64ae015e2d1d73c109c4d322 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 20:41:36 +0100 Subject: Have j.u.l. be invoked with TargetType.class.getName() instead of "TargetType" --- src/core/lombok/eclipse/handlers/HandleLog.java | 20 +++++++++++++++----- src/core/lombok/javac/handlers/HandleLog.java | 7 +++++-- .../transform/resource/after-delombok/LoggerJul.java | 6 +++--- test/transform/resource/after-ecj/LoggerJul.java | 6 +++--- 4 files changed, 26 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index 08f3e6f2..dfb45a29 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -42,7 +42,6 @@ import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.NameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; -import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; @@ -216,12 +215,23 @@ public class HandleLog { // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); COMMONS(lombok.jul.Log.class, "org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory", "getLog"), - // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("TargetType"); + // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(TargetType.class.getName()); JUL(lombok.jul.Log.class, "java.util.logging.Logger", "java.util.logging.Logger", "getLogger") { @Override public Expression createFactoryParameter(String typeName, Annotation source) { - Expression current = new StringLiteral(typeName.toCharArray(), source.sourceStart, source.sourceEnd, 0); - Eclipse.setGeneratedBy(current, source); - return current; + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + + MessageSend factoryParameterCall = new MessageSend(); + Eclipse.setGeneratedBy(factoryParameterCall, source); + + factoryParameterCall.receiver = super.createFactoryParameter(typeName, source); + factoryParameterCall.selector = "getName".toCharArray(); + + factoryParameterCall.nameSourcePosition = p; + factoryParameterCall.sourceStart = pS; + factoryParameterCall.sourceEnd = factoryParameterCall.statementEnd = pE; + + return factoryParameterCall; } }, diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 52a308ab..014895a1 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -155,10 +155,13 @@ public class HandleLog { // private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TargetType.class); COMMONS(lombok.jul.Log.class, "org.apache.commons.logging.Log", "org.apache.commons.logging.LogFactory.getLog"), - // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("TargetType"); + // private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(TargetType.class.getName()); JUL(lombok.jul.Log.class, "java.util.logging.Logger", "java.util.logging.Logger.getLogger") { @Override public JCExpression createFactoryParameter(JavacNode typeNode, String typeName) { - return typeNode.getTreeMaker().Literal(typeName); + TreeMaker maker = typeNode.getTreeMaker(); + JCExpression classAccess = super.createFactoryParameter(typeNode, typeName); + JCExpression method = maker.Select(classAccess, typeNode.toName("getName")); + return maker.Apply(List.nil(), method, List.nil()); } }, diff --git a/test/transform/resource/after-delombok/LoggerJul.java b/test/transform/resource/after-delombok/LoggerJul.java index a40bb2da..51f19926 100644 --- a/test/transform/resource/after-delombok/LoggerJul.java +++ b/test/transform/resource/after-delombok/LoggerJul.java @@ -1,9 +1,9 @@ class LoggerJul { - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("LoggerJul"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggerJul.class.getName()); } class LoggerJulString { - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("String"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(String.class.getName()); } class LoggerJulJavaLangString { - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("java.lang.String"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(java.lang.String.class.getName()); } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerJul.java b/test/transform/resource/after-ecj/LoggerJul.java index 734d0dac..99c1000c 100644 --- a/test/transform/resource/after-ecj/LoggerJul.java +++ b/test/transform/resource/after-ecj/LoggerJul.java @@ -1,5 +1,5 @@ @lombok.jul.Log class LoggerJul { - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("LoggerJul"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggerJul.class.getName()); () { } LoggerJul() { @@ -7,7 +7,7 @@ } } @lombok.jul.Log(String.class) class LoggerJulString { - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("String"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(String.class.getName()); () { } LoggerJulString() { @@ -15,7 +15,7 @@ } } @lombok.jul.Log(java.lang.String.class) class LoggerJulJavaLangString { - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("java.lang.String"); + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(java.lang.String.class.getName()); () { } LoggerJulJavaLangString() { -- cgit From 384bff18c9ff93f001aa8a938ba721914e101c0d Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Sat, 6 Nov 2010 21:17:44 +0100 Subject: implicit flags in interfaces (all methods become public abstract, etc) are now no longer printed in delombok --- .../lombok/delombok/PrettyCommentsPrinter.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src') diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 16c06f50..febb4b7f 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -657,6 +657,11 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } print(" "); + // + if ((tree.mods.flags & INTERFACE) != 0) { + removeImplicitModifiersForInterfaceMembers(tree.defs); + } + // if ((tree.mods.flags & ENUM) != 0) { printEnumBody(tree.defs); } else { @@ -668,6 +673,21 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } + // Added for delombok by Reinier Zwitserloot + private void removeImplicitModifiersForInterfaceMembers(List defs) { + for (JCTree def :defs) { + if (def instanceof JCVariableDecl) { + ((JCVariableDecl) def).mods.flags &= ~(Flags.PUBLIC | Flags.STATIC | Flags.FINAL); + } + if (def instanceof JCMethodDecl) { + ((JCMethodDecl) def).mods.flags &= ~(Flags.PUBLIC | Flags.ABSTRACT); + } + if (def instanceof JCClassDecl) { + ((JCClassDecl) def).mods.flags &= ~(Flags.PUBLIC | Flags.STATIC); + } + } + } + public void visitMethodDef(JCMethodDecl tree) { try { boolean isConstructor = tree.name == tree.name.table.fromChars("".toCharArray(), 0, 6); -- cgit From 8e7334a50535ef33189c3e71fcab0d9e625c6534 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 6 Nov 2010 23:29:43 +0100 Subject: Updated documentation on @Log and moved them all to lombok.extern.* --- buildScripts/website.ant.xml | 4 +- src/core/lombok/commons/Log.java | 34 ---------- src/core/lombok/eclipse/handlers/HandleLog.java | 32 ++++----- src/core/lombok/extern/apachecommons/Log.java | 77 ++++++++++++++++++++++ src/core/lombok/extern/jul/Log.java | 77 ++++++++++++++++++++++ src/core/lombok/extern/log4j/Log.java | 77 ++++++++++++++++++++++ src/core/lombok/extern/slf4j/Log.java | 76 +++++++++++++++++++++ src/core/lombok/javac/handlers/HandleLog.java | 32 ++++----- src/core/lombok/jul/Log.java | 34 ---------- src/core/lombok/log4j/Log.java | 34 ---------- src/core/lombok/slf4j/Log.java | 34 ---------- test/pretty/resource/after/Interfaces.java | 4 +- .../resource/after-ecj/LoggerCommons.java | 6 +- test/transform/resource/after-ecj/LoggerJul.java | 6 +- test/transform/resource/after-ecj/LoggerLog4j.java | 6 +- test/transform/resource/after-ecj/LoggerSlf4j.java | 4 +- .../after-ecj/LoggerSlf4jAlreadyExists.java | 2 +- .../after-ecj/LoggerSlf4jClassOfArray.java | 2 +- .../resource/after-ecj/LoggerSlf4jOnNonType.java | 2 +- .../resource/after-ecj/LoggerSlf4jTypes.java | 10 +-- .../resource/after-ecj/LoggerSlf4jWithClass.java | 8 +-- .../resource/after-ecj/LoggerSlf4jWithPackage.java | 4 +- test/transform/resource/before/LoggerCommons.java | 6 +- test/transform/resource/before/LoggerJul.java | 6 +- test/transform/resource/before/LoggerLog4j.java | 6 +- test/transform/resource/before/LoggerSlf4j.java | 4 +- .../resource/before/LoggerSlf4jAlreadyExists.java | 2 +- .../resource/before/LoggerSlf4jClassOfArray.java | 2 +- .../resource/before/LoggerSlf4jOnNonType.java | 2 +- .../resource/before/LoggerSlf4jTypes.java | 10 +-- .../resource/before/LoggerSlf4jWithClass.java | 8 +-- .../resource/before/LoggerSlf4jWithPackage.java | 4 +- usage_examples/LogExample_pre.jpage | 2 +- website/features/Log.html | 16 ++--- 34 files changed, 402 insertions(+), 231 deletions(-) delete mode 100644 src/core/lombok/commons/Log.java create mode 100644 src/core/lombok/extern/apachecommons/Log.java create mode 100644 src/core/lombok/extern/jul/Log.java create mode 100644 src/core/lombok/extern/log4j/Log.java create mode 100644 src/core/lombok/extern/slf4j/Log.java delete mode 100644 src/core/lombok/jul/Log.java delete mode 100644 src/core/lombok/log4j/Log.java delete mode 100644 src/core/lombok/slf4j/Log.java (limited to 'src') diff --git a/buildScripts/website.ant.xml b/buildScripts/website.ant.xml index 6ab8d509..08fc8a55 100644 --- a/buildScripts/website.ant.xml +++ b/buildScripts/website.ant.xml @@ -1,5 +1,5 @@