diff options
Diffstat (limited to 'src/core/lombok/javac')
-rw-r--r-- | src/core/lombok/javac/HandlerLibrary.java | 3 | ||||
-rw-r--r-- | src/core/lombok/javac/Javac.java | 239 | ||||
-rw-r--r-- | src/core/lombok/javac/JavacResolution.java | 3 | ||||
-rw-r--r-- | src/core/lombok/javac/TreeMirrorMaker.java | 85 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleCleanup.java | 8 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleConstructor.java | 16 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleDelegate.java | 9 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java | 76 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleGetter.java | 44 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleLog.java | 8 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleSetter.java | 17 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleSneakyThrows.java | 12 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleSynchronized.java | 12 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleToString.java | 25 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleVal.java | 9 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/JavacHandlerUtil.java | 237 |
16 files changed, 282 insertions, 521 deletions
diff --git a/src/core/lombok/javac/HandlerLibrary.java b/src/core/lombok/javac/HandlerLibrary.java index f0bd3442..d0cadab1 100644 --- a/src/core/lombok/javac/HandlerLibrary.java +++ b/src/core/lombok/javac/HandlerLibrary.java @@ -37,6 +37,7 @@ import lombok.core.SpiLoadUtil; import lombok.core.TypeLibrary; import lombok.core.TypeResolver; import lombok.core.AnnotationValues.AnnotationValueDecodeFail; +import lombok.javac.handlers.JavacHandlerUtil; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; @@ -77,7 +78,7 @@ public class HandlerLibrary { } public void handle(final JavacNode node) { - handler.handle(Javac.createAnnotation(annotationClass, node), (JCAnnotation)node.get(), node); + handler.handle(JavacHandlerUtil.createAnnotation(annotationClass, node), (JCAnnotation)node.get(), node); } } diff --git a/src/core/lombok/javac/Javac.java b/src/core/lombok/javac/Javac.java deleted file mode 100644 index 594539cd..00000000 --- a/src/core/lombok/javac/Javac.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright © 2009-2011 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; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; - -import lombok.Lombok; -import lombok.core.AST.Kind; -import lombok.core.AnnotationValues; -import lombok.core.AnnotationValues.AnnotationValue; -import lombok.core.TypeLibrary; -import lombok.core.TypeResolver; - -import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCAnnotation; -import com.sun.tools.javac.tree.JCTree.JCAssign; -import com.sun.tools.javac.tree.JCTree.JCExpression; -import com.sun.tools.javac.tree.JCTree.JCFieldAccess; -import com.sun.tools.javac.tree.JCTree.JCIdent; -import com.sun.tools.javac.tree.JCTree.JCLiteral; -import com.sun.tools.javac.tree.JCTree.JCNewArray; -import com.sun.tools.javac.tree.TreeScanner; -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; - -/** - * Container for static utility methods relevant to lombok's operation on javac. - */ -public class Javac { - private Javac() { - //prevent instantiation - } - - /** - * Checks if the Annotation AST Node provided is likely to be an instance of the provided annotation type. - * - * @param type An actual annotation type, such as {@code lombok.Getter.class}. - * @param node A Lombok AST node representing an annotation in source code. - */ - public static boolean annotationTypeMatches(Class<? extends Annotation> type, JavacNode node) { - if (node.getKind() != Kind.ANNOTATION) return false; - return typeMatches(type, node, ((JCAnnotation)node.get()).annotationType); - } - - /** - * Checks if the given TypeReference node is likely to be a reference to the provided class. - * - * @param type An actual type. This method checks if {@code typeNode} is likely to be a reference to this type. - * @param node A Lombok AST node. Any node in the appropriate compilation unit will do (used to get access to import statements). - * @param typeNode A type reference to check. - */ - public static boolean typeMatches(Class<?> type, JavacNode node, JCTree typeNode) { - String typeName = typeNode.toString(); - - TypeLibrary library = new TypeLibrary(); - library.addType(type.getName()); - TypeResolver resolver = new TypeResolver(library, node.getPackageDeclaration(), node.getImportStatements()); - Collection<String> typeMatches = resolver.findTypeMatches(node, typeName); - - for (String match : typeMatches) { - if (match.equals(type.getName())) return true; - } - - return false; - } - - /** - * Creates an instance of {@code AnnotationValues} for the provided AST Node. - * - * @param type An annotation class type, such as {@code lombok.Getter.class}. - * @param node A Lombok AST node representing an annotation in source code. - */ - public static <A extends Annotation> AnnotationValues<A> createAnnotation(Class<A> type, final JavacNode node) { - Map<String, AnnotationValue> values = new HashMap<String, AnnotationValue>(); - JCAnnotation anno = (JCAnnotation) node.get(); - List<JCExpression> arguments = anno.getArguments(); - for (Method m : type.getDeclaredMethods()) { - if (!Modifier.isPublic(m.getModifiers())) continue; - String name = m.getName(); - List<String> raws = new ArrayList<String>(); - List<Object> guesses = new ArrayList<Object>(); - List<Object> expressions = new ArrayList<Object>(); - final List<DiagnosticPosition> positions = new ArrayList<DiagnosticPosition>(); - boolean isExplicit = false; - - for (JCExpression arg : arguments) { - String mName; - JCExpression rhs; - - if (arg instanceof JCAssign) { - JCAssign assign = (JCAssign) arg; - mName = assign.lhs.toString(); - rhs = assign.rhs; - } else { - rhs = arg; - mName = "value"; - } - - if (!mName.equals(name)) continue; - isExplicit = true; - if (rhs instanceof JCNewArray) { - List<JCExpression> elems = ((JCNewArray)rhs).elems; - for (JCExpression inner : elems) { - raws.add(inner.toString()); - expressions.add(inner); - guesses.add(calculateGuess(inner)); - positions.add(inner.pos()); - } - } else { - raws.add(rhs.toString()); - expressions.add(rhs); - guesses.add(calculateGuess(rhs)); - positions.add(rhs.pos()); - } - } - - values.put(name, new AnnotationValue(node, raws, expressions, guesses, isExplicit) { - @Override public void setError(String message, int valueIdx) { - if (valueIdx < 0) node.addError(message); - else node.addError(message, positions.get(valueIdx)); - } - @Override public void setWarning(String message, int valueIdx) { - if (valueIdx < 0) node.addWarning(message); - else node.addWarning(message, positions.get(valueIdx)); - } - }); - } - - return new AnnotationValues<A>(type, values, node); - } - - /** - * Turns an expression into a guessed intended literal. Only works for literals, as you can imagine. - * - * Will for example turn a TrueLiteral into 'Boolean.valueOf(true)'. - */ - private static Object calculateGuess(JCExpression expr) { - if (expr instanceof JCLiteral) { - JCLiteral lit = (JCLiteral)expr; - if (lit.getKind() == com.sun.source.tree.Tree.Kind.BOOLEAN_LITERAL) { - return ((Number)lit.value).intValue() == 0 ? false : true; - } - return lit.value; - } else if (expr instanceof JCIdent || expr instanceof JCFieldAccess) { - String x = expr.toString(); - if (x.endsWith(".class")) x = x.substring(0, x.length() - 6); - else { - int idx = x.lastIndexOf('.'); - if (idx > -1) x = x.substring(idx + 1); - } - return x; - } else return null; - } - - /** - * Retrieves a compile time constant of type int from the specified class location. - * - * Solves the problem of compile time constant inlining, resulting in lombok having the wrong value - * (javac compiler changes private api constants from time to time) - * - * @param ctcLocation location of the compile time constant - * @param identifier the name of the field of the compile time constant. - */ - public static int getCtcInt(Class<?> ctcLocation, String identifier) { - try { - return (Integer)ctcLocation.getField(identifier).get(null); - } catch (NoSuchFieldException e) { - throw Lombok.sneakyThrow(e); - } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); - } - } - - private static class MarkingScanner extends TreeScanner { - private final JCTree source; - - MarkingScanner(JCTree source) { - this.source = source; - } - - @Override public void scan(JCTree tree) { - setGeneratedBy(tree, source); - super.scan(tree); - } - } - - private static Map<JCTree, JCTree> generatedNodes = new WeakHashMap<JCTree, JCTree>(); - - public static JCTree getGeneratedBy(JCTree node) { - synchronized (generatedNodes) { - return generatedNodes.get(node); - } - } - - public static boolean isGenerated(JCTree node) { - return getGeneratedBy(node) != null; - } - - public static <T extends JCTree> T recursiveSetGeneratedBy(T node, JCTree source) { - setGeneratedBy(node, source); - node.accept(new MarkingScanner(source)); - - return node; - } - - public static <T extends JCTree> T setGeneratedBy(T node, JCTree source) { - synchronized (generatedNodes) { - if (source == null) generatedNodes.remove(node); - else generatedNodes.put(node, source); - } - return node; - } -} diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index a116b503..e0d56b85 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -48,6 +48,7 @@ public class JavacResolution { 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. @@ -297,7 +298,7 @@ public class JavacResolution { EnvFinder finder = new EnvFinder(node.getContext()); while (!stack.isEmpty()) stack.pop().accept(finder); - TreeMirrorMaker mirrorMaker = new TreeMirrorMaker(node); + TreeMirrorMaker mirrorMaker = new TreeMirrorMaker(node.getTreeMaker()); JCTree copy = mirrorMaker.copy(finder.copyAt()); attrib(copy, finder.get()); diff --git a/src/core/lombok/javac/TreeMirrorMaker.java b/src/core/lombok/javac/TreeMirrorMaker.java deleted file mode 100644 index 2036e414..00000000 --- a/src/core/lombok/javac/TreeMirrorMaker.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright © 2010-2011 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; - -import java.util.Collections; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.Map; - -import com.sun.source.tree.VariableTree; -import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeCopier; -import com.sun.tools.javac.util.List; - -public class TreeMirrorMaker extends TreeCopier<Void> { - private final IdentityHashMap<JCTree, JCTree> originalToCopy = new IdentityHashMap<JCTree, JCTree>(); - - public TreeMirrorMaker(JavacNode node) { - super(node.getTreeMaker()); - } - - @Override public <T extends JCTree> T copy(T original) { - T copy = super.copy(original); - originalToCopy.put(original, copy); - return copy; - } - - @Override public <T extends JCTree> T copy(T original, Void p) { - T copy = super.copy(original, p); - originalToCopy.put(original, copy); - return copy; - } - - @Override public <T extends JCTree> List<T> copy(List<T> originals) { - List<T> copies = super.copy(originals); - if (originals != null) { - Iterator<T> it1 = originals.iterator(); - Iterator<T> it2 = copies.iterator(); - while (it1.hasNext()) originalToCopy.put(it1.next(), it2.next()); - } - return copies; - } - - @Override public <T extends JCTree> List<T> copy(List<T> originals, Void p) { - List<T> copies = super.copy(originals, p); - if (originals != null) { - Iterator<T> it1 = originals.iterator(); - Iterator<T> it2 = copies.iterator(); - while (it1.hasNext()) originalToCopy.put(it1.next(), it2.next()); - } - return copies; - } - - public Map<JCTree, JCTree> getOriginalToCopyMap() { - return Collections.unmodifiableMap(originalToCopy); - } - - // Fix for NPE in HandleVal. See http://code.google.com/p/projectlombok/issues/detail?id=205 - // Maybe this should be done elsewhere... - @Override public JCTree visitVariable(VariableTree node, Void p) { - JCVariableDecl copy = (JCVariableDecl) super.visitVariable(node, p); - copy.sym = ((JCVariableDecl) node).sym; - return copy; - } -} diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 43dacda2..5b77554c 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -21,7 +21,7 @@ */ package lombok.javac.handlers; -import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary; +import static lombok.javac.handlers.JavacHandlerUtil.*; import lombok.Cleanup; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; @@ -122,9 +122,9 @@ public class HandleCleanup extends JavacAnnotationHandler<Cleanup> { JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null); - JCBlock finalizer = Javac.recursiveSetGeneratedBy(maker.Block(0, List.<JCStatement>of(ifNotNullCleanup)), ast); + JCBlock finalizer = recursiveSetGeneratedBy(maker.Block(0, List.<JCStatement>of(ifNotNullCleanup)), ast); - newStatements.append(Javac.setGeneratedBy(maker.Try(Javac.setGeneratedBy(maker.Block(0, tryBlock.toList()), ast), List.<JCCatch>nil(), finalizer), ast)); + newStatements.append(setGeneratedBy(maker.Try(setGeneratedBy(maker.Block(0, tryBlock.toList()), ast), List.<JCCatch>nil(), finalizer), ast)); if (blockNode instanceof JCBlock) { ((JCBlock)blockNode).stats = newStatements.toList(); @@ -138,7 +138,7 @@ public class HandleCleanup extends JavacAnnotationHandler<Cleanup> { } private JCMethodInvocation preventNullAnalysis(TreeMaker maker, JavacNode node, JCExpression expression) { - JCMethodInvocation singletonList = maker.Apply(List.<JCExpression>nil(), JavacHandlerUtil.chainDotsString(maker, node, "java.util.Collections.singletonList"), List.of(expression)); + JCMethodInvocation singletonList = maker.Apply(List.<JCExpression>nil(), chainDotsString(node, "java.util.Collections.singletonList"), List.of(expression)); JCMethodInvocation cleanedExpr = maker.Apply(List.<JCExpression>nil(), maker.Select(singletonList, node.toName("get")) , List.<JCExpression>of(maker.Literal(TypeTags.INT, 0))); return cleanedExpr; } diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 212daf16..88ff523f 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -27,12 +27,10 @@ import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.core.AnnotationValues; +import lombok.core.TransformationsUtil; import lombok.core.AST.Kind; -import lombok.core.handlers.TransformationsUtil; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; -import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; import org.mangosdk.spi.ProviderFor; @@ -160,9 +158,9 @@ public class HandleConstructor { if (skipIfConstructorExists) { for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(NoArgsConstructor.class, child) || - Javac.annotationTypeMatches(AllArgsConstructor.class, child) || - Javac.annotationTypeMatches(RequiredArgsConstructor.class, child)) + if (annotationTypeMatches(NoArgsConstructor.class, child) || + annotationTypeMatches(AllArgsConstructor.class, child) || + annotationTypeMatches(RequiredArgsConstructor.class, child)) return; } } @@ -181,7 +179,7 @@ public class HandleConstructor { private static void addConstructorProperties(JCModifiers mods, JavacNode node, List<JavacNode> fields) { if (fields.isEmpty()) return; TreeMaker maker = node.getTreeMaker(); - JCExpression constructorPropertiesType = chainDots(maker, node, "java", "beans", "ConstructorProperties"); + JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties"); ListBuffer<JCExpression> fieldNames = ListBuffer.lb(); for (JavacNode field : fields) { fieldNames.append(maker.Literal(field.getName())); @@ -221,7 +219,7 @@ public class HandleConstructor { if (!suppressConstructorProperties && level != AccessLevel.PRIVATE && !isLocalType(typeNode)) { addConstructorProperties(mods, typeNode, fields); } - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"), + return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"), null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), maker.Block(0L, nullChecks.appendList(assigns).toList()), null), source); } @@ -280,6 +278,6 @@ public class HandleConstructor { JCReturn returnStatement = maker.Return(maker.NewClass(null, List.<JCExpression>nil(), constructorType, args.toList(), null)); JCBlock body = maker.Block(0, List.<JCStatement>of(returnStatement)); - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName(name), returnType, typeParams.toList(), params.toList(), List.<JCExpression>nil(), body, null), source); + return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName(name), returnType, typeParams.toList(), params.toList(), List.<JCExpression>nil(), body, null), source); } } diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java index 0294171f..9f8e5e91 100644 --- a/src/core/lombok/javac/handlers/HandleDelegate.java +++ b/src/core/lombok/javac/handlers/HandleDelegate.java @@ -21,7 +21,7 @@ */ package lombok.javac.handlers; -import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary; +import static lombok.javac.handlers.JavacHandlerUtil.*; import java.util.ArrayList; import java.util.Arrays; @@ -43,7 +43,6 @@ import lombok.Delegate; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.javac.FindTypeVarScanner; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.JavacResolution; @@ -186,7 +185,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { } for (JCMethodDecl method : toAdd) { - JavacHandlerUtil.injectMethod(annotation.up().up(), method); + injectMethod(annotation.up().up(), method); } } @@ -254,7 +253,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { com.sun.tools.javac.util.List<JCAnnotation> annotations; if (sig.isDeprecated) { annotations = com.sun.tools.javac.util.List.of(maker.Annotation( - JavacHandlerUtil.chainDots(maker, annotation, "java", "lang", "Deprecated"), + chainDots(annotation, "java", "lang", "Deprecated"), com.sun.tools.javac.util.List.<JCExpression>nil())); } else { annotations = com.sun.tools.javac.util.List.nil(); @@ -295,7 +294,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { JCStatement body = useReturn ? maker.Return(delegateCall) : maker.Exec(delegateCall); JCBlock bodyBlock = maker.Block(0, com.sun.tools.javac.util.List.of(body)); - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, sig.name, returnType, toList(typeParams), toList(params), toList(thrown), bodyBlock, null), annotation.get()); + return recursiveSetGeneratedBy(maker.MethodDef(mods, sig.name, returnType, toList(typeParams), toList(params), toList(thrown), bodyBlock, null), annotation.get()); } private static <T> com.sun.tools.javac.util.List<T> toList(ListBuffer<T> collection) { diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index afd299ef..50bcdd3e 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.*; +import static lombok.javac.Javac.getCtcInt; import java.util.ArrayList; import java.util.Collections; @@ -29,7 +30,6 @@ import java.util.Collections; import lombok.EqualsAndHashCode; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; @@ -103,7 +103,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode source) { for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(EqualsAndHashCode.class, child)) { + if (annotationTypeMatches(EqualsAndHashCode.class, child)) { //The annotation will make it happen, so we can skip it. return; } @@ -209,9 +209,9 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); - JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); + JCAnnotation overrideAnnotation = maker.Annotation(chainDots(typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); - JCExpression returnType = maker.TypeIdent(Javac.getCtcInt(TypeTags.class, "INT")); + JCExpression returnType = maker.TypeIdent(getCtcInt(TypeTags.class, "INT")); ListBuffer<JCStatement> statements = ListBuffer.lb(); Name primeName = typeNode.toName("PRIME"); @@ -219,12 +219,12 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* final int PRIME = 31; */ { if (!fields.isEmpty() || callSuper) { statements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), - primeName, maker.TypeIdent(Javac.getCtcInt(TypeTags.class, "INT")), maker.Literal(31))); + primeName, maker.TypeIdent(getCtcInt(TypeTags.class, "INT")), maker.Literal(31))); } } /* int result = 1; */ { - statements.append(maker.VarDef(maker.Modifiers(0), resultName, maker.TypeIdent(Javac.getCtcInt(TypeTags.class, "INT")), maker.Literal(1))); + statements.append(maker.VarDef(maker.Modifiers(0), resultName, maker.TypeIdent(getCtcInt(TypeTags.class, "INT")), maker.Literal(1))); } ListBuffer<JCExpression> intoResult = ListBuffer.lb(); @@ -253,7 +253,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* Float.floatToIntBits(this.fieldName) */ intoResult.append(maker.Apply( List.<JCExpression>nil(), - chainDots(maker, typeNode, "java", "lang", "Float", "floatToIntBits"), + chainDots(typeNode, "java", "lang", "Float", "floatToIntBits"), List.of(fieldAccessor))); break; case DOUBLE: @@ -261,7 +261,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas Name tempVar = typeNode.toName("temp" + (++tempCounter)); JCExpression init = maker.Apply( List.<JCExpression>nil(), - chainDots(maker, typeNode, "java", "lang", "Double", "doubleToLongBits"), + chainDots(typeNode, "java", "lang", "Double", "doubleToLongBits"), List.of(fieldAccessor)); statements.append( maker.VarDef(maker.Modifiers(Flags.FINAL), tempVar, maker.TypeIdent(TypeTags.LONG), init)); @@ -282,14 +282,14 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas boolean primitiveArray = ((JCArrayTypeTree)fType).elemtype instanceof JCPrimitiveTypeTree; boolean useDeepHC = multiDim || !primitiveArray; - JCExpression hcMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepHC ? "deepHashCode" : "hashCode"); + JCExpression hcMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepHC ? "deepHashCode" : "hashCode"); intoResult.append( maker.Apply(List.<JCExpression>nil(), hcMethod, List.of(fieldAccessor))); } else /* objects */ { /* this.fieldName == null ? 0 : this.fieldName.hashCode() */ JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(createFieldAccessor(maker, fieldNode, fieldAccess), typeNode.toName("hashCode")), List.<JCExpression>nil()); - JCExpression thisEqualsNull = maker.Binary(Javac.getCtcInt(JCTree.class, "EQ"), fieldAccessor, maker.Literal(Javac.getCtcInt(TypeTags.class, "BOT"), null)); + JCExpression thisEqualsNull = maker.Binary(getCtcInt(JCTree.class, "EQ"), fieldAccessor, maker.Literal(getCtcInt(TypeTags.class, "BOT"), null)); intoResult.append( maker.Conditional(thisEqualsNull, maker.Literal(0), hcCall)); } @@ -298,8 +298,8 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas /* fold each intoResult entry into: result = result * PRIME + (item); */ for (JCExpression expr : intoResult) { - JCExpression mult = maker.Binary(Javac.getCtcInt(JCTree.class, "MUL"), maker.Ident(resultName), maker.Ident(primeName)); - JCExpression add = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), mult, expr); + JCExpression mult = maker.Binary(getCtcInt(JCTree.class, "MUL"), maker.Ident(resultName), maker.Ident(primeName)); + JCExpression add = maker.Binary(getCtcInt(JCTree.class, "PLUS"), mult, expr); statements.append(maker.Exec(maker.Assign(maker.Ident(resultName), add))); } @@ -308,16 +308,16 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } JCBlock body = maker.Block(0, statements.toList()); - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("hashCode"), returnType, + return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("hashCode"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source); } /** The 2 references must be clones of each other. */ private JCExpression longToIntForHashCode(TreeMaker maker, JCExpression ref1, JCExpression ref2) { /* (int)(ref >>> 32 ^ ref) */ - JCExpression shift = maker.Binary(Javac.getCtcInt(JCTree.class, "USR"), ref1, maker.Literal(32)); - JCExpression xorBits = maker.Binary(Javac.getCtcInt(JCTree.class, "BITXOR"), shift, ref2); - return maker.TypeCast(maker.TypeIdent(Javac.getCtcInt(TypeTags.class, "INT")), xorBits); + JCExpression shift = maker.Binary(getCtcInt(JCTree.class, "USR"), ref1, maker.Literal(32)); + JCExpression xorBits = maker.Binary(getCtcInt(JCTree.class, "BITXOR"), shift, ref2); + return maker.TypeCast(maker.TypeIdent(getCtcInt(TypeTags.class, "INT")), xorBits); } private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source) { @@ -328,21 +328,21 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas Name otherName = typeNode.toName("other"); Name thisName = typeNode.toName("this"); - JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); + JCAnnotation overrideAnnotation = maker.Annotation(chainDots(typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); - JCExpression objectType = chainDots(maker, typeNode, "java", "lang", "Object"); - JCExpression returnType = maker.TypeIdent(Javac.getCtcInt(TypeTags.class, "BOOLEAN")); + JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); + JCExpression returnType = maker.TypeIdent(getCtcInt(TypeTags.class, "BOOLEAN")); ListBuffer<JCStatement> statements = ListBuffer.lb(); final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), oName, objectType, null)); /* if (o == this) return true; */ { - statements.append(maker.If(maker.Binary(Javac.getCtcInt(JCTree.class, "EQ"), maker.Ident(oName), + statements.append(maker.If(maker.Binary(getCtcInt(JCTree.class, "EQ"), maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null)); } /* if (!(o instanceof MyType) return false; */ { - JCUnary notInstanceOf = maker.Unary(Javac.getCtcInt(JCTree.class, "NOT"), maker.TypeTest(maker.Ident(oName), maker.Ident(type.name))); + JCUnary notInstanceOf = maker.Unary(getCtcInt(JCTree.class, "NOT"), maker.TypeTest(maker.Ident(oName), maker.Ident(type.name))); statements.append(maker.If(notInstanceOf, returnBool(maker, false), null)); } @@ -373,11 +373,11 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas if (needsCanEqual) { List<JCExpression> exprNil = List.nil(); JCExpression thisRef = maker.Ident(thisName); - JCExpression castThisRef = maker.TypeCast(chainDots(maker, typeNode, "java", "lang", "Object"), thisRef); + JCExpression castThisRef = maker.TypeCast(chainDots(typeNode, "java", "lang", "Object"), thisRef); JCExpression equalityCheck = maker.Apply(exprNil, maker.Select(maker.Ident(otherName), typeNode.toName("canEqual")), List.of(castThisRef)); - statements.append(maker.If(maker.Unary(Javac.getCtcInt(JCTree.class, "NOT"), equalityCheck), returnBool(maker, false), null)); + statements.append(maker.If(maker.Unary(getCtcInt(JCTree.class, "NOT"), equalityCheck), returnBool(maker, false), null)); } } @@ -386,7 +386,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(oName))); - JCUnary superNotEqual = maker.Unary(Javac.getCtcInt(JCTree.class, "NOT"), callToSuper); + JCUnary superNotEqual = maker.Unary(getCtcInt(JCTree.class, "NOT"), callToSuper); statements.append(maker.If(superNotEqual, returnBool(maker, false), null)); } @@ -407,7 +407,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas default: /* if (this.fieldName != other.fieldName) return false; */ statements.append( - maker.If(maker.Binary(Javac.getCtcInt(JCTree.class, "NE"), thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null)); + maker.If(maker.Binary(getCtcInt(JCTree.class, "NE"), thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null)); break; } } else if (fType instanceof JCArrayTypeTree) { @@ -416,20 +416,20 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas boolean primitiveArray = ((JCArrayTypeTree)fType).elemtype instanceof JCPrimitiveTypeTree; boolean useDeepEquals = multiDim || !primitiveArray; - JCExpression eqMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals"); + JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals"); List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor); - statements.append(maker.If(maker.Unary(Javac.getCtcInt(JCTree.class, "NOT"), + statements.append(maker.If(maker.Unary(getCtcInt(JCTree.class, "NOT"), maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null)); } else /* objects */ { /* if (this.fieldName == null ? other.fieldName != null : !this.fieldName.equals(other.fieldName)) return false; */ - JCExpression thisEqualsNull = maker.Binary(Javac.getCtcInt(JCTree.class, "EQ"), thisFieldAccessor, maker.Literal(Javac.getCtcInt(TypeTags.class, "BOT"), null)); - JCExpression otherNotEqualsNull = maker.Binary(Javac.getCtcInt(JCTree.class, "NE"), otherFieldAccessor, maker.Literal(Javac.getCtcInt(TypeTags.class, "BOT"), null)); + JCExpression thisEqualsNull = maker.Binary(getCtcInt(JCTree.class, "EQ"), thisFieldAccessor, maker.Literal(getCtcInt(TypeTags.class, "BOT"), null)); + JCExpression otherNotEqualsNull = maker.Binary(getCtcInt(JCTree.class, "NE"), otherFieldAccessor, maker.Literal(getCtcInt(TypeTags.class, "BOT"), null)); JCExpression equalsArg = createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName)); - JCExpression castEqualsArg = maker.TypeCast(chainDots(maker, typeNode, "java", "lang", "Object"), equalsArg); + JCExpression castEqualsArg = maker.TypeCast(chainDots(typeNode, "java", "lang", "Object"), equalsArg); JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(), maker.Select(createFieldAccessor(maker, fieldNode, fieldAccess), typeNode.toName("equals")), List.of(castEqualsArg)); - JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(Javac.getCtcInt(JCTree.class, "NOT"), thisEqualsThat)); + JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(getCtcInt(JCTree.class, "NOT"), thisEqualsThat)); statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null)); } } @@ -439,7 +439,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } JCBlock body = maker.Block(0, statements.toList()); - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); + return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); } private JCMethodDecl createCanEqual(JavacNode typeNode, JCTree source) { @@ -451,29 +451,29 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas JCClassDecl type = (JCClassDecl) typeNode.get(); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.<JCAnnotation>nil()); - JCExpression returnType = maker.TypeIdent(Javac.getCtcInt(TypeTags.class, "BOOLEAN")); + JCExpression returnType = maker.TypeIdent(getCtcInt(TypeTags.class, "BOOLEAN")); Name canEqualName = typeNode.toName("canEqual"); - JCExpression objectType = chainDots(maker, typeNode, "java", "lang", "Object"); + JCExpression objectType = chainDots(typeNode, "java", "lang", "Object"); Name otherName = typeNode.toName("other"); List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(Flags.FINAL), otherName, objectType, null)); JCBlock body = maker.Block(0, List.<JCStatement>of( maker.Return(maker.TypeTest(maker.Ident(otherName), maker.Ident(type.name))))); - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); + return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); } private JCStatement generateCompareFloatOrDouble(JCExpression thisDotField, JCExpression otherDotField, TreeMaker maker, JavacNode node, boolean isDouble) { /* if (Float.compare(fieldName, other.fieldName) != 0) return false; */ - JCExpression clazz = chainDots(maker, node, "java", "lang", isDouble ? "Double" : "Float"); + JCExpression clazz = chainDots(node, "java", "lang", isDouble ? "Double" : "Float"); List<JCExpression> args = List.of(thisDotField, otherDotField); - JCBinary compareCallEquals0 = maker.Binary(Javac.getCtcInt(JCTree.class, "NE"), maker.Apply( + JCBinary compareCallEquals0 = maker.Binary(getCtcInt(JCTree.class, "NE"), maker.Apply( List.<JCExpression>nil(), maker.Select(clazz, node.toName("compare")), args), maker.Literal(0)); return maker.If(compareCallEquals0, returnBool(maker, false), null); } private JCStatement returnBool(TreeMaker maker, boolean bool) { - return maker.Return(maker.Literal(Javac.getCtcInt(TypeTags.class, "BOOLEAN"), bool ? 1 : 0)); + return maker.Return(maker.Literal(getCtcInt(TypeTags.class, "BOOLEAN"), bool ? 1 : 0)); } } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index a7e357ad..77a63839 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.*; +import static lombok.javac.Javac.*; import java.util.Collection; import java.util.Collections; @@ -31,9 +32,8 @@ import java.util.Map; import lombok.AccessLevel; import lombok.Getter; import lombok.core.AnnotationValues; +import lombok.core.TransformationsUtil; import lombok.core.AST.Kind; -import lombok.core.handlers.TransformationsUtil; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; @@ -74,7 +74,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { if (checkForTypeLevelGetter) { if (typeNode != null) for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(Getter.class, child)) { + if (annotationTypeMatches(Getter.class, child)) { //The annotation will make it happen, so we can skip it. return; } @@ -125,7 +125,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, boolean lazy) { for (JavacNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(Getter.class, child)) { + if (annotationTypeMatches(Getter.class, child)) { //The annotation will make it happen, so we can skip it. return; } @@ -242,10 +242,10 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { List<JCAnnotation> annsOnMethod = nonNulls.appendList(nullables); - JCMethodDecl decl = Javac.recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, + JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source); - if (toClearOfMarkers != null) Javac.recursiveSetGeneratedBy(toClearOfMarkers, null); + if (toClearOfMarkers != null) recursiveSetGeneratedBy(toClearOfMarkers, null); return decl; } @@ -260,14 +260,14 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { private static final java.util.Map<Integer, String> TYPE_MAP; static { Map<Integer, String> m = new HashMap<Integer, String>(); - m.put(Javac.getCtcInt(TypeTags.class, "INT"), "java.lang.Integer"); - m.put(Javac.getCtcInt(TypeTags.class, "DOUBLE"), "java.lang.Double"); - m.put(Javac.getCtcInt(TypeTags.class, "FLOAT"), "java.lang.Float"); - m.put(Javac.getCtcInt(TypeTags.class, "SHORT"), "java.lang.Short"); - m.put(Javac.getCtcInt(TypeTags.class, "BYTE"), "java.lang.Byte"); - m.put(Javac.getCtcInt(TypeTags.class, "LONG"), "java.lang.Long"); - m.put(Javac.getCtcInt(TypeTags.class, "BOOLEAN"), "java.lang.Boolean"); - m.put(Javac.getCtcInt(TypeTags.class, "CHAR"), "java.lang.Character"); + m.put(getCtcInt(TypeTags.class, "INT"), "java.lang.Integer"); + m.put(getCtcInt(TypeTags.class, "DOUBLE"), "java.lang.Double"); + m.put(getCtcInt(TypeTags.class, "FLOAT"), "java.lang.Float"); + m.put(getCtcInt(TypeTags.class, "SHORT"), "java.lang.Short"); + m.put(getCtcInt(TypeTags.class, "BYTE"), "java.lang.Byte"); + m.put(getCtcInt(TypeTags.class, "LONG"), "java.lang.Long"); + m.put(getCtcInt(TypeTags.class, "BOOLEAN"), "java.lang.Boolean"); + m.put(getCtcInt(TypeTags.class, "CHAR"), "java.lang.Character"); TYPE_MAP = Collections.unmodifiableMap(m); } @@ -293,14 +293,14 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { if (field.vartype instanceof JCPrimitiveTypeTree) { String boxed = TYPE_MAP.get(((JCPrimitiveTypeTree)field.vartype).typetag); if (boxed != null) { - field.vartype = chainDotsString(maker, fieldNode, boxed); + field.vartype = chainDotsString(fieldNode, boxed); } } Name valueName = fieldNode.toName("value"); /* java.util.concurrent.atomic.AtomicReference<ValueType> value = this.fieldName.get();*/ { - JCTypeApply valueVarType = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))); + JCTypeApply valueVarType = maker.TypeApply(chainDotsString(fieldNode, AR), List.of(copyType(maker, field))); statements.append(maker.VarDef(maker.Modifiers(0), valueName, valueVarType, callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD)))); } @@ -316,7 +316,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { /* if (value == null) { */ { ListBuffer<JCStatement> innerIfStatements = ListBuffer.lb(); /* value = new java.util.concurrent.atomic.AtomicReference<ValueType>(new ValueType());*/ { - JCTypeApply valueVarType = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))); + JCTypeApply valueVarType = maker.TypeApply(chainDotsString(fieldNode, AR), List.of(copyType(maker, field))); JCNewClass newInstance = maker.NewClass(null, NIL_EXPRESSION, valueVarType, List.<JCExpression>of(field.init), null); JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), newInstance)); @@ -327,7 +327,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { innerIfStatements.append(statement); } - JCBinary isNull = maker.Binary(Javac.getCtcInt(JCTree.class, "EQ"), maker.Ident(valueName), maker.Literal(Javac.getCtcInt(TypeTags.class, "BOT"), null)); + JCBinary isNull = maker.Binary(getCtcInt(JCTree.class, "EQ"), maker.Ident(valueName), maker.Literal(getCtcInt(TypeTags.class, "BOT"), null)); JCIf ifStatement = maker.If(isNull, maker.Block(0, innerIfStatements.toList()), null); synchronizedStatements.append(ifStatement); } @@ -335,7 +335,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { synchronizedStatement = maker.Synchronized(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Block(0, synchronizedStatements.toList())); } - JCBinary isNull = maker.Binary(Javac.getCtcInt(JCTree.class, "EQ"), maker.Ident(valueName), maker.Literal(Javac.getCtcInt(TypeTags.class, "BOT"), null)); + JCBinary isNull = maker.Binary(getCtcInt(JCTree.class, "EQ"), maker.Ident(valueName), maker.Literal(getCtcInt(TypeTags.class, "BOT"), null)); JCIf ifStatement = maker.If(isNull, maker.Block(0, List.<JCStatement>of(synchronizedStatement)), null); statements.append(ifStatement); } @@ -345,10 +345,10 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { // update the field type and init last /* private final java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<ValueType> fieldName = new java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<ValueType>>(); */ { - field.vartype = Javac.recursiveSetGeneratedBy( - maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.<JCExpression>of(maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))))), + field.vartype = recursiveSetGeneratedBy( + maker.TypeApply(chainDotsString(fieldNode, AR), List.<JCExpression>of(maker.TypeApply(chainDotsString(fieldNode, AR), List.of(copyType(maker, field))))), source); - field.init = Javac.recursiveSetGeneratedBy(maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null), source); + field.init = recursiveSetGeneratedBy(maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null), source); } return statements.toList(); diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 885bd538..d084e5b6 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -26,10 +26,8 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import java.lang.annotation.Annotation; import lombok.core.AnnotationValues; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; -import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; import org.mangosdk.spi.ProviderFor; @@ -86,13 +84,13 @@ public class HandleLog { TreeMaker maker = typeNode.getTreeMaker(); // private static final <loggerType> log = <factoryMethod>(<parameter>); - JCExpression loggerType = chainDotsString(maker, typeNode, framework.getLoggerTypeName()); - JCExpression factoryMethod = chainDotsString(maker, typeNode, framework.getLoggerFactoryMethodName()); + JCExpression loggerType = chainDotsString(typeNode, framework.getLoggerTypeName()); + JCExpression factoryMethod = chainDotsString(typeNode, framework.getLoggerFactoryMethodName()); JCExpression loggerName = framework.createFactoryParameter(typeNode, loggingType); JCMethodInvocation factoryMethodCall = maker.Apply(List.<JCExpression>nil(), factoryMethod, List.<JCExpression>of(loggerName)); - JCVariableDecl fieldDecl = Javac.recursiveSetGeneratedBy(maker.VarDef( + JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | Flags.STATIC), typeNode.toName("log"), loggerType, factoryMethodCall), source); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index d899336f..e7a97214 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.*; +import static lombok.javac.Javac.*; import java.util.Collection; @@ -33,11 +34,9 @@ import lombok.AccessLevel; import lombok.Setter; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; -import lombok.core.handlers.TransformationsUtil; -import lombok.javac.Javac; +import lombok.core.TransformationsUtil; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; -import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; @@ -68,7 +67,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { if (checkForTypeLevelSetter) { if (typeNode != null) for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(Setter.class, child)) { + if (annotationTypeMatches(Setter.class, child)) { //The annotation will make it happen, so we can skip it. return; } @@ -118,7 +117,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { public void generateSetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) { for (JavacNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(Setter.class, child)) { + if (annotationTypeMatches(Setter.class, child)) { //The annotation will make it happen, so we can skip it. return; } @@ -211,14 +210,14 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { List<JCAnnotation> annsOnParam = nonNulls.appendList(nullables); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); //WARNING: Do not use field.getSymbolTable().voidType - that field has gone through non-backwards compatible API changes within javac1.6. - JCExpression methodType = treeMaker.Type(new JCNoType(Javac.getCtcInt(TypeTags.class, "VOID"))); + JCExpression methodType = treeMaker.Type(new JCNoType(getCtcInt(TypeTags.class, "VOID"))); List<JCTypeParameter> methodGenericParams = List.nil(); List<JCVariableDecl> parameters = List.of(param); List<JCExpression> throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - return Javac.recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, List.<JCAnnotation>nil()), methodName, methodType, + return recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, List.<JCAnnotation>nil()), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source); } @@ -229,8 +228,8 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { @Override public TypeKind getKind() { - if (tag == Javac.getCtcInt(TypeTags.class, "VOID")) return TypeKind.VOID; - if (tag == Javac.getCtcInt(TypeTags.class, "NONE")) return TypeKind.NONE; + if (tag == getCtcInt(TypeTags.class, "VOID")) return TypeKind.VOID; + if (tag == getCtcInt(TypeTags.class, "NONE")) return TypeKind.NONE; throw new AssertionError("Unexpected tag: " + tag); } diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index 5b20d79e..8f6e12d6 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -21,8 +21,7 @@ */ package lombok.javac.handlers; -import static lombok.javac.handlers.JavacHandlerUtil.chainDots; -import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary; +import static lombok.javac.handlers.JavacHandlerUtil.*; import java.util.ArrayList; import java.util.Collection; @@ -30,7 +29,6 @@ import java.util.Collections; import lombok.SneakyThrows; import lombok.core.AnnotationValues; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; @@ -99,16 +97,16 @@ public class HandleSneakyThrows extends JavacAnnotationHandler<SneakyThrows> { private JCStatement buildTryCatchBlock(JavacNode node, List<JCStatement> contents, String exception, JCTree source) { TreeMaker maker = node.getTreeMaker(); - JCBlock tryBlock = Javac.setGeneratedBy(maker.Block(0, contents), source); + JCBlock tryBlock = setGeneratedBy(maker.Block(0, contents), source); - JCExpression varType = chainDots(maker, node, exception.split("\\.")); + JCExpression varType = chainDots(node, exception.split("\\.")); JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL), node.toName("$ex"), varType, null); - JCExpression lombokLombokSneakyThrowNameRef = chainDots(maker, node, "lombok", "Lombok", "sneakyThrow"); + JCExpression lombokLombokSneakyThrowNameRef = chainDots(node, "lombok", "Lombok", "sneakyThrow"); JCBlock catchBody = maker.Block(0, List.<JCStatement>of(maker.Throw(maker.Apply( List.<JCExpression>nil(), lombokLombokSneakyThrowNameRef, List.<JCExpression>of(maker.Ident(node.toName("$ex"))))))); - return Javac.setGeneratedBy(maker.Try(tryBlock, List.of(Javac.recursiveSetGeneratedBy(maker.Catch(catchParam, catchBody), source)), null), source); + return setGeneratedBy(maker.Try(tryBlock, List.of(recursiveSetGeneratedBy(maker.Catch(catchParam, catchBody), source)), null), source); } } diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index fa4a0474..8cdfff68 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -83,11 +83,11 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> { annotationNode.addError("The field " + lockName + " does not exist."); return; } - JCExpression objectType = chainDots(maker, methodNode, "java", "lang", "Object"); + JCExpression objectType = chainDots(methodNode, "java", "lang", "Object"); //We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable! - JCNewArray newObjectArray = maker.NewArray(chainDots(maker, methodNode, "java", "lang", "Object"), + JCNewArray newObjectArray = maker.NewArray(chainDots(methodNode, "java", "lang", "Object"), List.<JCExpression>of(maker.Literal(Javac.getCtcInt(TypeTags.class, "INT"), 0)), null); - JCVariableDecl fieldDecl = Javac.recursiveSetGeneratedBy(maker.VarDef( + JCVariableDecl fieldDecl = recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)), methodNode.toName(lockName), objectType, newObjectArray), ast); injectFieldSuppressWarnings(methodNode.up(), fieldDecl); @@ -97,13 +97,13 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> { JCExpression lockNode; if (isStatic) { - lockNode = chainDots(maker, methodNode, methodNode.up().getName(), lockName); + lockNode = chainDots(methodNode, methodNode.up().getName(), lockName); } else { lockNode = maker.Select(maker.Ident(methodNode.toName("this")), methodNode.toName(lockName)); } - Javac.recursiveSetGeneratedBy(lockNode, ast); - method.body = Javac.setGeneratedBy(maker.Block(0, List.<JCStatement>of(Javac.setGeneratedBy(maker.Synchronized(lockNode, method.body), ast))), ast); + recursiveSetGeneratedBy(lockNode, ast); + method.body = setGeneratedBy(maker.Block(0, List.<JCStatement>of(setGeneratedBy(maker.Synchronized(lockNode, method.body), ast))), ast); methodNode.rebuild(); } diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 06e70e7a..80f77dc7 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -22,14 +22,13 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.*; +import static lombok.javac.Javac.getCtcInt; import lombok.ToString; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; -import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; -import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; import org.mangosdk.spi.ProviderFor; @@ -98,7 +97,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) { for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { - if (Javac.annotationTypeMatches(ToString.class, child)) { + if (annotationTypeMatches(ToString.class, child)) { //The annotation will make it happen, so we can skip it. return; } @@ -171,9 +170,9 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { private JCMethodDecl createToString(JavacNode typeNode, List<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); - JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); + JCAnnotation overrideAnnotation = maker.Annotation(chainDots(typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation)); - JCExpression returnType = chainDots(maker, typeNode, "java", "lang", "String"); + JCExpression returnType = chainDots(typeNode, "java", "lang", "String"); boolean first = true; @@ -197,7 +196,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), List.<JCExpression>nil()); - current = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), current, callToSuper); + current = maker.Binary(getCtcInt(JCTree.class, "PLUS"), current, callToSuper); first = false; } @@ -212,32 +211,32 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { boolean primitiveArray = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCPrimitiveTypeTree; boolean useDeepTS = multiDim || !primitiveArray; - JCExpression hcMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepTS ? "deepToString" : "toString"); + JCExpression hcMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepTS ? "deepToString" : "toString"); expr = maker.Apply(List.<JCExpression>nil(), hcMethod, List.<JCExpression>of(fieldAccessor)); } else expr = fieldAccessor; if (first) { - current = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), current, expr); + current = maker.Binary(getCtcInt(JCTree.class, "PLUS"), current, expr); first = false; continue; } if (includeFieldNames) { - current = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), current, maker.Literal(infix + fieldNode.getName() + "=")); + current = maker.Binary(getCtcInt(JCTree.class, "PLUS"), current, maker.Literal(infix + fieldNode.getName() + "=")); } else { - current = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), current, maker.Literal(infix)); + current = maker.Binary(getCtcInt(JCTree.class, "PLUS"), current, maker.Literal(infix)); } - current = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), current, expr); + current = maker.Binary(getCtcInt(JCTree.class, "PLUS"), current, expr); } - if (!first) current = maker.Binary(Javac.getCtcInt(JCTree.class, "PLUS"), current, maker.Literal(suffix)); + if (!first) current = maker.Binary(getCtcInt(JCTree.class, "PLUS"), current, maker.Literal(suffix)); JCStatement returnStatement = maker.Return(current); JCBlock body = maker.Block(0, List.of(returnStatement)); - return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, + return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source); } diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java index bc70899d..b8de8996 100644 --- a/src/core/lombok/javac/handlers/HandleVal.java +++ b/src/core/lombok/javac/handlers/HandleVal.java @@ -21,8 +21,9 @@ */ package lombok.javac.handlers; +import static lombok.javac.handlers.JavacHandlerUtil.*; + import lombok.val; -import lombok.javac.Javac; import lombok.javac.JavacASTAdapter; import lombok.javac.JavacASTVisitor; import lombok.javac.JavacNode; @@ -51,7 +52,7 @@ public class HandleVal extends JavacASTAdapter { JCTree source = local.vartype; - if (!Javac.typeMatches(val.class, localNode, local.vartype)) return; + if (!typeMatches(val.class, localNode, local.vartype)) return; JCExpression rhsOfEnhancedForLoop = null; if (local.init == null) { @@ -77,7 +78,7 @@ public class HandleVal extends JavacASTAdapter { local.mods.flags |= Flags.FINAL; if (!localNode.shouldDeleteLombokAnnotations()) { - JCAnnotation valAnnotation = Javac.recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), source); + JCAnnotation valAnnotation = recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), source); local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation); } @@ -126,7 +127,7 @@ public class HandleVal extends JavacASTAdapter { local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst()); throw e; } finally { - Javac.recursiveSetGeneratedBy(local.vartype, source); + recursiveSetGeneratedBy(local.vartype, source); } } } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index c733304b..fedd9d47 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -21,23 +21,33 @@ */ package lombok.javac.handlers; -import static lombok.javac.Javac.annotationTypeMatches; +import static lombok.javac.Javac.*; import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.WeakHashMap; import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.Data; import lombok.Getter; import lombok.core.AnnotationValues; +import lombok.core.TypeLibrary; +import lombok.core.TypeResolver; import lombok.core.AST.Kind; -import lombok.core.handlers.TransformationsUtil; +import lombok.core.AnnotationValues.AnnotationValue; import lombok.javac.Javac; import lombok.javac.JavacNode; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.JCTree.JCLiteral; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.TreeMaker; @@ -56,6 +66,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; /** * Container for static utility methods useful to handlers written for javac. @@ -65,12 +76,142 @@ public class JavacHandlerUtil { //Prevent instantiation } + private static class MarkingScanner extends TreeScanner { + private final JCTree source; + + MarkingScanner(JCTree source) { + this.source = source; + } + + @Override public void scan(JCTree tree) { + setGeneratedBy(tree, source); + super.scan(tree); + } + } + + private static Map<JCTree, JCTree> generatedNodes = new WeakHashMap<JCTree, JCTree>(); + + public static JCTree getGeneratedBy(JCTree node) { + synchronized (generatedNodes) { + return generatedNodes.get(node); + } + } + + public static boolean isGenerated(JCTree node) { + return getGeneratedBy(node) != null; + } + + public static <T extends JCTree> T recursiveSetGeneratedBy(T node, JCTree source) { + setGeneratedBy(node, source); + node.accept(new MarkingScanner(source)); + + return node; + } + + public static <T extends JCTree> T setGeneratedBy(T node, JCTree source) { + synchronized (generatedNodes) { + if (source == null) generatedNodes.remove(node); + else generatedNodes.put(node, source); + } + return node; + } + /** - * Checks if the given expression (that really ought to refer to a type expression) represents a primitive type. + * Checks if the Annotation AST Node provided is likely to be an instance of the provided annotation type. + * + * @param type An actual annotation type, such as {@code lombok.Getter.class}. + * @param node A Lombok AST node representing an annotation in source code. + */ + public static boolean annotationTypeMatches(Class<? extends Annotation> type, JavacNode node) { + if (node.getKind() != Kind.ANNOTATION) return false; + return typeMatches(type, node, ((JCAnnotation)node.get()).annotationType); + } + + /** + * Checks if the given TypeReference node is likely to be a reference to the provided class. + * + * @param type An actual type. This method checks if {@code typeNode} is likely to be a reference to this type. + * @param node A Lombok AST node. Any node in the appropriate compilation unit will do (used to get access to import statements). + * @param typeNode A type reference to check. + */ + public static boolean typeMatches(Class<?> type, JavacNode node, JCTree typeNode) { + String typeName = typeNode.toString(); + + TypeLibrary library = new TypeLibrary(); + library.addType(type.getName()); + TypeResolver resolver = new TypeResolver(library, node.getPackageDeclaration(), node.getImportStatements()); + Collection<String> typeMatches = resolver.findTypeMatches(node, typeName); + + for (String match : typeMatches) { + if (match.equals(type.getName())) return true; + } + + return false; + } + + /** + * Creates an instance of {@code AnnotationValues} for the provided AST Node. + * + * @param type An annotation class type, such as {@code lombok.Getter.class}. + * @param node A Lombok AST node representing an annotation in source code. */ - public static boolean isPrimitive(JCExpression ref) { - String typeName = ref.toString(); - return TransformationsUtil.PRIMITIVE_TYPE_NAME_PATTERN.matcher(typeName).matches(); + public static <A extends Annotation> AnnotationValues<A> createAnnotation(Class<A> type, final JavacNode node) { + Map<String, AnnotationValue> values = new HashMap<String, AnnotationValue>(); + JCAnnotation anno = (JCAnnotation) node.get(); + List<JCExpression> arguments = anno.getArguments(); + for (Method m : type.getDeclaredMethods()) { + if (!Modifier.isPublic(m.getModifiers())) continue; + String name = m.getName(); + java.util.List<String> raws = new ArrayList<String>(); + java.util.List<Object> guesses = new ArrayList<Object>(); + java.util.List<Object> expressions = new ArrayList<Object>(); + final java.util.List<DiagnosticPosition> positions = new ArrayList<DiagnosticPosition>(); + boolean isExplicit = false; + + for (JCExpression arg : arguments) { + String mName; + JCExpression rhs; + + if (arg instanceof JCAssign) { + JCAssign assign = (JCAssign) arg; + mName = assign.lhs.toString(); + rhs = assign.rhs; + } else { + rhs = arg; + mName = "value"; + } + + if (!mName.equals(name)) continue; + isExplicit = true; + if (rhs instanceof JCNewArray) { + List<JCExpression> elems = ((JCNewArray)rhs).elems; + for (JCExpression inner : elems) { + raws.add(inner.toString()); + expressions.add(inner); + guesses.add(calculateGuess(inner)); + positions.add(inner.pos()); + } + } else { + raws.add(rhs.toString()); + expressions.add(rhs); + guesses.add(calculateGuess(rhs)); + positions.add(rhs.pos()); + } + } + + values.put(name, new AnnotationValue(node, raws, expressions, guesses, isExplicit) { + @Override public void setError(String message, int valueIdx) { + if (valueIdx < 0) node.addError(message); + else node.addError(message, positions.get(valueIdx)); + } + @Override public void setWarning(String message, int valueIdx) { + if (valueIdx < 0) node.addWarning(message); + else node.addWarning(message, positions.get(valueIdx)); + } + }); + } + + return new AnnotationValues<A>(type, values, node); } /** @@ -133,56 +274,6 @@ public class JavacHandlerUtil { return newAnnotations.toList(); } - /** - * Translates the given field into all possible getter names. - * Convenient wrapper around {@link TransformationsUtil#toAllGetterNames(CharSequence, boolean)}. - */ - public static java.util.List<String> toAllGetterNames(JCVariableDecl field) { - CharSequence fieldName = field.name; - - boolean isBoolean = field.vartype.toString().equals("boolean"); - - return TransformationsUtil.toAllGetterNames(fieldName, isBoolean); - } - - /** - * @return the likely getter name for the stated field. (e.g. private boolean foo; to isFoo). - * - * Convenient wrapper around {@link TransformationsUtil#toGetterName(CharSequence, boolean)}. - */ - public static String toGetterName(JCVariableDecl field) { - CharSequence fieldName = field.name; - - boolean isBoolean = field.vartype.toString().equals("boolean"); - - return TransformationsUtil.toGetterName(fieldName, isBoolean); - } - - /** - * Translates the given field into all possible setter names. - * Convenient wrapper around {@link TransformationsUtil#toAllSetterNames(CharSequence, boolean)}. - */ - public static java.util.List<String> toAllSetterNames(JCVariableDecl field) { - CharSequence fieldName = field.name; - - boolean isBoolean = field.vartype.toString().equals("boolean"); - - return TransformationsUtil.toAllSetterNames(fieldName, isBoolean); - } - - /** - * @return the likely setter name for the stated field. (e.g. private boolean foo; to setFoo). - * - * Convenient wrapper around {@link TransformationsUtil#toSetterName(CharSequence, boolean)}. - */ - public static String toSetterName(JCVariableDecl field) { - CharSequence fieldName = field.name; - - boolean isBoolean = field.vartype.toString().equals("boolean"); - - return TransformationsUtil.toSetterName(fieldName, isBoolean); - } - /** Serves as return value for the methods that check for the existence of fields and methods. */ public enum MemberExistsResult { NOT_EXISTS, EXISTS_BY_LOMBOK, EXISTS_BY_USER; @@ -203,7 +294,7 @@ public class JavacHandlerUtil { for (JCTree def : ((JCClassDecl)node.get()).defs) { if (def instanceof JCVariableDecl) { if (((JCVariableDecl)def).name.contentEquals(fieldName)) { - return Javac.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; + return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -234,7 +325,7 @@ public class JavacHandlerUtil { if (def instanceof JCMethodDecl) { String name = ((JCMethodDecl)def).name.toString(); boolean matches = caseSensitive ? name.equals(methodName) : name.equalsIgnoreCase(methodName); - if (matches) return Javac.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; + if (matches) return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -258,7 +349,7 @@ public class JavacHandlerUtil { if (def instanceof JCMethodDecl) { if (((JCMethodDecl)def).name.contentEquals("<init>")) { if ((((JCMethodDecl)def).mods.flags & Flags.GENERATEDCONSTR) != 0) continue; - return Javac.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; + return getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -318,7 +409,7 @@ public class JavacHandlerUtil { for (JavacNode child : field.down()) { if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Getter.class, child)) { - AnnotationValues<Getter> ann = Javac.createAnnotation(Getter.class, child); + AnnotationValues<Getter> ann = createAnnotation(Getter.class, child); if (ann.getInstance().value() == AccessLevel.NONE) return null; //Definitely WONT have a getter. hasGetterAnnotation = true; } @@ -333,7 +424,7 @@ public class JavacHandlerUtil { if (containingType != null) for (JavacNode child : containingType.down()) { if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Data.class, child)) hasGetterAnnotation = true; if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Getter.class, child)) { - AnnotationValues<Getter> ann = Javac.createAnnotation(Getter.class, child); + AnnotationValues<Getter> ann = createAnnotation(Getter.class, child); if (ann.getInstance().value() == AccessLevel.NONE) return null; //Definitely WONT have a getter. hasGetterAnnotation = true; } @@ -359,8 +450,8 @@ public class JavacHandlerUtil { // If @Getter(lazy = true) is used, then using it is mandatory. for (JavacNode child : field.down()) { if (child.getKind() != Kind.ANNOTATION) continue; - if (Javac.annotationTypeMatches(Getter.class, child)) { - AnnotationValues<Getter> ann = Javac.createAnnotation(Getter.class, child); + if (annotationTypeMatches(Getter.class, child)) { + AnnotationValues<Getter> ann = createAnnotation(Getter.class, child); if (ann.getInstance().lazy()) return true; } } @@ -440,7 +531,7 @@ public class JavacHandlerUtil { private static void injectField(JavacNode typeNode, JCVariableDecl field, boolean addSuppressWarnings) { JCClassDecl type = (JCClassDecl) typeNode.get(); - if (addSuppressWarnings) addSuppressWarningsAll(field.mods, typeNode, field.pos, Javac.getGeneratedBy(field)); + if (addSuppressWarnings) addSuppressWarningsAll(field.mods, typeNode, field.pos, getGeneratedBy(field)); type.defs = type.defs.append(field); typeNode.add(field, Kind.FIELD); @@ -471,7 +562,7 @@ public class JavacHandlerUtil { } } - addSuppressWarningsAll(method.mods, typeNode, method.pos, Javac.getGeneratedBy(method)); + addSuppressWarningsAll(method.mods, typeNode, method.pos, getGeneratedBy(method)); type.defs = type.defs.append(method); typeNode.add(method, Kind.METHOD); @@ -479,11 +570,11 @@ public class JavacHandlerUtil { private static void addSuppressWarningsAll(JCModifiers mods, JavacNode node, int pos, JCTree source) { TreeMaker maker = node.getTreeMaker(); - JCExpression suppressWarningsType = chainDots(maker, node, "java", "lang", "SuppressWarnings"); + JCExpression suppressWarningsType = chainDots(node, "java", "lang", "SuppressWarnings"); JCLiteral allLiteral = maker.Literal("all"); suppressWarningsType.pos = pos; allLiteral.pos = pos; - JCAnnotation annotation = Javac.recursiveSetGeneratedBy(maker.Annotation(suppressWarningsType, List.<JCExpression>of(allLiteral)), source); + JCAnnotation annotation = recursiveSetGeneratedBy(maker.Annotation(suppressWarningsType, List.<JCExpression>of(allLiteral)), source); annotation.pos = pos; mods.annotations = mods.annotations.append(annotation); } @@ -507,13 +598,13 @@ public class JavacHandlerUtil { * @see com.sun.tools.javac.tree.JCTree.JCIdent * @see com.sun.tools.javac.tree.JCTree.JCFieldAccess */ - public static JCExpression chainDots(TreeMaker maker, JavacNode node, String... elems) { + public static JCExpression chainDots(JavacNode node, String... elems) { assert elems != null; assert elems.length > 0; - JCExpression e = maker.Ident(node.toName(elems[0])); + JCExpression e = node.getTreeMaker().Ident(node.toName(elems[0])); for (int i = 1 ; i < elems.length ; i++) { - e = maker.Select(e, node.toName(elems[i])); + e = node.getTreeMaker().Select(e, node.toName(elems[i])); } return e; @@ -530,8 +621,8 @@ public class JavacHandlerUtil { * @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("\\.")); + public static JCExpression chainDotsString(JavacNode node, String elems) { + return chainDots(node, elems.split("\\.")); } /** @@ -563,7 +654,7 @@ public class JavacHandlerUtil { JCVariableDecl varDecl = (JCVariableDecl) variable.get(); if (isPrimitive(varDecl.vartype)) return null; Name fieldName = varDecl.name; - JCExpression npe = chainDots(treeMaker, variable, "java", "lang", "NullPointerException"); + JCExpression npe = chainDots(variable, "java", "lang", "NullPointerException"); JCTree exception = treeMaker.NewClass(null, List.<JCExpression>nil(), npe, List.<JCExpression>of(treeMaker.Literal(fieldName.toString())), null); JCStatement throwStatement = treeMaker.Throw(exception); return treeMaker.If(treeMaker.Binary(Javac.getCtcInt(JCTree.class, "EQ"), treeMaker.Ident(fieldName), treeMaker.Literal(Javac.getCtcInt(TypeTags.class, "BOT"), null)), throwStatement, null); |